ALSAStreamOps.cpp revision 466e8a8fa8d4e6186b72c25cd0289356828177b3
14765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* ALSAStreamOps.cpp 24765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 34765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Copyright 2008-2009 Wind River Systems 44765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Copyright (c) 2011, Code Aurora Forum. All rights reserved. 54765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 64765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Licensed under the Apache License, Version 2.0 (the "License"); 74765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** you may not use this file except in compliance with the License. 84765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** You may obtain a copy of the License at 94765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** http://www.apache.org/licenses/LICENSE-2.0 114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** 124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** Unless required by applicable law or agreed to in writing, software 134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** distributed under the License is distributed on an "AS IS" BASIS, 144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** See the License for the specific language governing permissions and 164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ** limitations under the License. 174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <errno.h> 204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdarg.h> 214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/stat.h> 224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <fcntl.h> 234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdlib.h> 244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <unistd.h> 254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <dlfcn.h> 264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 279746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_TAG "ALSAStreamOps" 284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev//#define LOG_NDEBUG 0 299746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#define LOG_NDDEBUG 0 304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <utils/Log.h> 314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <utils/String8.h> 324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <cutils/properties.h> 344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <media/AudioRecord.h> 354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <hardware_legacy/power.h> 364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "AudioHardwareALSA.h" 384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevnamespace android_audio_legacy 404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// ---------------------------------------------------------------------------- 434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 444765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevALSAStreamOps::ALSAStreamOps(AudioHardwareALSA *parent, alsa_handle_t *handle) : 454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent(parent), 464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mHandle(handle) 474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 504765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevALSAStreamOps::~ALSAStreamOps() 514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev Mutex::Autolock autoLock(mParent->mLock); 534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((mParent->mVoipStreamCount)) { 574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mVoipStreamCount--; 584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(mParent->mVoipStreamCount > 0) { 594113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("ALSAStreamOps::close() Ignore"); 604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return ; 614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mVoipStreamCount = 0; 644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mVoipBitRate = 0; 654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev close(); 674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for(ALSAHandleList::iterator it = mParent->mDeviceList.begin(); 694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it != mParent->mDeviceList.end(); ++it) { 704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mHandle == &(*it)) { 714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev it->useCase[0] = 0; 724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mDeviceList.erase(it); 734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// use emulated popcount optimization 794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// http://www.df.lth.se/~john_e/gems/gem002d.html 804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic inline uint32_t popCount(uint32_t u) 814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev u = ((u&0x55555555) + ((u>>1)&0x55555555)); 834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev u = ((u&0x33333333) + ((u>>2)&0x33333333)); 844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f)); 854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff)); 864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev u = ( u&0x0000ffff) + (u>>16); 874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return u; 884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t ALSAStreamOps::set(int *format, 914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *channels, 924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t *rate, 934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t device) 944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevices = device; 964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (channels && *channels != 0) { 974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mHandle->channels != popCount(*channels)) 984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return BAD_VALUE; 994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (channels) { 1004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels = 0; 1014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mHandle->devices & AudioSystem::DEVICE_OUT_ALL) { 1024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(mHandle->channels) { 1034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 4: 1044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_OUT_BACK_LEFT; 1054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_OUT_BACK_RIGHT; 1064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Fall through... 1074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 1084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 2: 1094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_OUT_FRONT_RIGHT; 1104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Fall through... 1114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 1: 1124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_OUT_FRONT_LEFT; 1134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 1164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(mHandle->channels) { 1179746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED 1184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // For 5.1 recording 1194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 6 : 1204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_IN_5POINT1; 1214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 1234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Do not fall through... 1244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 1254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 2: 1264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_IN_RIGHT; 1274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Fall through... 1284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 1: 1294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *channels |= AudioSystem::CHANNEL_IN_LEFT; 1304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (rate && *rate > 0) { 1364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mHandle->sampleRate != *rate) 1374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return BAD_VALUE; 1384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else if (rate) { 1394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *rate = mHandle->sampleRate; 1404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_pcm_format_t iformat = mHandle->format; 1434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (format) { 1454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(*format) { 1464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::FORMAT_DEFAULT: 1474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::PCM_16_BIT: 1504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev iformat = SNDRV_PCM_FORMAT_S16_LE; 1514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::AMR_NB: 1534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::AMR_WB: 1549746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_QCHAT_ENABLED 1554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRC: 1564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRCB: 1574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRCWB: 1584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 1594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev iformat = *format; 1604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::PCM_8_BIT: 1634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev iformat = SNDRV_PCM_FORMAT_S8; 1644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 1674113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGE("Unknown PCM format %i. Forcing default", *format); 1684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mHandle->format != iformat) 1724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return BAD_VALUE; 1734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(iformat) { 1754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case SNDRV_PCM_FORMAT_S16_LE: 1764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *format = AudioSystem::PCM_16_BIT; 1774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case SNDRV_PCM_FORMAT_S8: 1794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev *format = AudioSystem::PCM_8_BIT; 1804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 1824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 1834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 1874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t ALSAStreamOps::setParameters(const String8& keyValuePairs) 1904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioParameter param = AudioParameter(keyValuePairs); 1924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 key = String8(AudioParameter::keyRouting); 1934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int device; 19474060dee8c9a414ad0345176e2422de18a4ff183ty.lee 19574060dee8c9a414ad0345176e2422de18a4ff183ty.lee#ifdef SEPERATED_AUDIO_INPUT 19674060dee8c9a414ad0345176e2422de18a4ff183ty.lee String8 key_input = String8(AudioParameter::keyInputSource); 19774060dee8c9a414ad0345176e2422de18a4ff183ty.lee int source; 19874060dee8c9a414ad0345176e2422de18a4ff183ty.lee 19974060dee8c9a414ad0345176e2422de18a4ff183ty.lee if (param.getInt(key_input, source) == NO_ERROR) { 20074060dee8c9a414ad0345176e2422de18a4ff183ty.lee ALOGD("setParameters(), input_source = %d", source); 20174060dee8c9a414ad0345176e2422de18a4ff183ty.lee mParent->mALSADevice->setInput(source); 20274060dee8c9a414ad0345176e2422de18a4ff183ty.lee param.remove(key_input); 20374060dee8c9a414ad0345176e2422de18a4ff183ty.lee } 20474060dee8c9a414ad0345176e2422de18a4ff183ty.lee#endif 20574060dee8c9a414ad0345176e2422de18a4ff183ty.lee 2064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.getInt(key, device) == NO_ERROR) { 2074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Ignore routing if device is 0. 2084113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("setParameters(): keyRouting with device %d", device); 209466e8a8fa8d4e6186b72c25cd0289356828177b3Eric Laurent // reset to speaker when disconnecting HDMI to avoid timeout due to write errors 210466e8a8fa8d4e6186b72c25cd0289356828177b3Eric Laurent if ((device == 0) && (mDevices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) { 211466e8a8fa8d4e6186b72c25cd0289356828177b3Eric Laurent device = AudioSystem::DEVICE_OUT_SPEAKER; 212466e8a8fa8d4e6186b72c25cd0289356828177b3Eric Laurent } 2134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevices = device; 2144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(device) { 2154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->doRouting(device); 2164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 2184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2199746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_FM_ENABLED 2204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else { 2214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(AudioParameter::keyHandleFm); 2224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.getInt(key, device) == NO_ERROR) { 2234113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("setParameters(): handleFm with device %d", device); 2244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mDevices = device; 2254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(device) { 2264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->handleFm(device); 2274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.remove(key); 2294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 2324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return NO_ERROR; 2344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2364765c439491ddda3de658e62cc4a64d10e726b34Iliyan MalchevString8 ALSAStreamOps::getParameters(const String8& keys) 2374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev AudioParameter param = AudioParameter(keys); 2394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 value; 2404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev String8 key = String8(AudioParameter::keyRouting); 2414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 2434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.addInt(key, (int)mDevices); 2444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else { 2469746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_VOIP_ENABLED 2474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev key = String8(AudioParameter::keyVoipCheck); 2484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param.get(key, value) == NO_ERROR) { 2494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) || 2504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) 2514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.addInt(key, true); 2524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 2534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param.addInt(key, false); 2544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2554113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev#endif 2564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2574113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("getParameters() %s", param.toString().string()); 2584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return param.toString(); 2594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevuint32_t ALSAStreamOps::sampleRate() const 2624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return mHandle->sampleRate; 2644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// 2674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// Return the number of bytes (not frames) 2684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// 2694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevsize_t ALSAStreamOps::bufferSize() const 2704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2714113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGV("bufferSize() returns %d", mHandle->bufferSize); 2724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return mHandle->bufferSize; 2734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 2744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint ALSAStreamOps::format() const 2764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 2774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int audioSystemFormat; 2784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev snd_pcm_format_t ALSAFormat = mHandle->format; 2804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(ALSAFormat) { 2824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case SNDRV_PCM_FORMAT_S8: 2834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audioSystemFormat = AudioSystem::PCM_8_BIT; 2844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 2854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::AMR_NB: 2874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::AMR_WB: 2889746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_QCHAT_ENABLED 2894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRC: 2904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRCB: 2914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case AudioSystem::EVRCWB: 2924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 2934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audioSystemFormat = mHandle->format; 2944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 2954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case SNDRV_PCM_FORMAT_S16_LE: 2964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audioSystemFormat = AudioSystem::PCM_16_BIT; 2974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 2984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 3004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev LOG_FATAL("Unknown AudioSystem bit width %d!", audioSystemFormat); 3014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev audioSystemFormat = AudioSystem::PCM_16_BIT; 3024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 3034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3059efed76df6b7c75d170e8f900f875f4329587719SathishKumar Mani ALOGV("ALSAFormat:0x%x,audioSystemFormat:0x%x",ALSAFormat,audioSystemFormat); 3064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return audioSystemFormat; 3074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevuint32_t ALSAStreamOps::channels() const 3104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned int count = mHandle->channels; 3124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t channels = 0; 3134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mDevices & AudioSystem::DEVICE_OUT_ALL) 3154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(count) { 3164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 4: 3174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_OUT_BACK_LEFT; 3184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_OUT_BACK_RIGHT; 3194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Fall through... 3204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 3214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 2: 3224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_OUT_FRONT_RIGHT; 3234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Fall through... 3244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 1: 3254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_OUT_FRONT_LEFT; 3264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 3274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 3294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch(count) { 3309746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_SSR_ENABLED 3314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // For 5.1 recording 3324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 6 : 3334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_IN_5POINT1; 3344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 3354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Do not fall through... 3364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 3374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 3384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 2: 3394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_IN_RIGHT; 3404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Fall through... 3414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 1: 3424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev channels |= AudioSystem::CHANNEL_IN_LEFT; 3434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 3444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return channels; 3474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevvoid ALSAStreamOps::close() 3504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3514113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("close"); 3524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) || 3534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) { 3544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mVoipBitRate = 0; 3554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mVoipStreamCount = 0; 3564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mParent->mALSADevice->close(mHandle); 3584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// 3614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// Set playback or capture PCM device. It's possible to support audio output 3624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// or input from multiple devices by using the ALSA plugins, but this is 3634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// not supported for simplicity. 3644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// 3654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// The AudioHardwareALSA API does not allow one to set the input routing. 3664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// 3674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// If the "routes" value does not map to a valid device, the default playback 3684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// device is used. 3694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev// 3704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatus_t ALSAStreamOps::open(int mode) 3714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 3724113f34dfbaa8d82a5e1ef0265e916317161984dIliyan Malchev ALOGD("open"); 3734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return mParent->mALSADevice->open(mHandle); 3744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 3754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} // namespace androidi_audio_legacy 377