1a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland/* 28dd179b07f00e35208dd4cf48e14264717e8d5a0Jean-Baptiste Queru** Copyright 2008, The Android Open-Source Project 3a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland** 47510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 57510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** you may not use this file except in compliance with the License. 67510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** You may obtain a copy of the License at 7a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland** 87510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 9a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland** 107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 117510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 127510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project** See the License for the specific language governing permissions and 14a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland** limitations under the License. 15a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland*/ 16a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 17a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <math.h> 18a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 197510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project//#define LOG_NDEBUG 0 20a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#define LOG_TAG "AudioHardwareMSM72XX" 21a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <utils/Log.h> 22a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <utils/String8.h> 23a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 24a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <stdio.h> 25a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <unistd.h> 26a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <sys/ioctl.h> 27a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <sys/types.h> 28a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <sys/stat.h> 29a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <dlfcn.h> 30a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include <fcntl.h> 31a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 32a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// hardware specific functions 33a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 34a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#include "AudioHardware.h" 359e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks#include <media/AudioRecord.h> 36a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 37a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 38a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 39a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandnamespace android { 407510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatic int audpre_index, tx_iir_index; 417510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatic void * acoustic; 427510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectconst uint32_t AudioHardware::inputSamplingRates[] = { 437510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 447510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project}; 45a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 46a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 47a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioHardware() : 487510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0), 492735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mOutput(0), mSndEndpoints(NULL), mCurSndDevice(-1), 50a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland SND_DEVICE_CURRENT(-1), 51a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland SND_DEVICE_HANDSET(-1), 527510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project SND_DEVICE_SPEAKER(-1), 53a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland SND_DEVICE_HEADSET(-1), 542735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_BT(-1), 552735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_CARKIT(-1), 562735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_TTY_FULL(-1), 572735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_TTY_VCO(-1), 582735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_TTY_HCO(-1), 592735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_NO_MIC_HEADSET(-1), 602735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_FM_HEADSET(-1), 612735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_HEADSET_AND_SPEAKER(-1), 622735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_FM_SPEAKER(-1), 632735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent SND_DEVICE_BT_EC_OFF(-1) 64a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 65a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 667510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*snd_get_num)(); 677510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*snd_get_endpoint)(int, msm_snd_endpoint *); 687510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*set_acoustic_parameters)(); 697510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 707510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project struct msm_snd_endpoint *ept; 717510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 727510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 737510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (acoustic == NULL ) { 74c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open libhtc_acoustic.so"); 75d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland /* this is not really an error on non-htc devices... */ 76d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland mNumSndEndpoints = 0; 7735f70b5d158659c59981365ecd8e2acfb09b3181Brian Swetland mInit = true; 787510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return; 797510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 807510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 817510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 827510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if ((*set_acoustic_parameters) == 0 ) { 83c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open set_acoustic_parameters()"); 843ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev return; 853ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev } 863ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev 877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int rc = set_acoustic_parameters(); 887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (rc < 0) { 89c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not set acoustic parameters to share memory: %d", rc); 907510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project// return; 917510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 927510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 937510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints"); 947510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if ((*snd_get_num) == 0 ) { 95c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open snd_get_num()"); 967510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project// return; 977510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 987510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 997510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mNumSndEndpoints = snd_get_num(); 100f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("mNumSndEndpoints = %d", mNumSndEndpoints); 1017510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints]; 1027510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mInit = true; 10322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("constructed %d SND endpoints)", mNumSndEndpoints); 1047510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ept = mSndEndpoints; 1057510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint"); 1067510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if ((*snd_get_endpoint) == 0 ) { 107c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open snd_get_endpoint()"); 1087510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return; 1097510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 1107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 1117510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) { 1127510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ept->id = cnt; 1137510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snd_get_endpoint(cnt, ept); 1147510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project#define CHECK_FOR(desc) \ 1157510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!strcmp(ept->name, #desc)) { \ 1167510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project SND_DEVICE_##desc = ept->id; \ 117f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("BT MATCH " #desc); \ 1187510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } else 1197510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(CURRENT) 1207510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(HANDSET) 1217510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(SPEAKER) 1227510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(BT) 1237510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(BT_EC_OFF) 1247510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(HEADSET) 1252735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(CARKIT) 1262735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(TTY_FULL) 1272735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(TTY_VCO) 1282735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(TTY_HCO) 1292735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(NO_MIC_HEADSET) 1302735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(FM_HEADSET) 1312735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent CHECK_FOR(FM_SPEAKER) 1327510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(HEADSET_AND_SPEAKER) {} 133a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#undef CHECK_FOR 134a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 135a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 136a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 137a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::~AudioHardware() 138a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 1392735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent for (size_t index = 0; index < mInputs.size(); index++) { 1402735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent closeInputStream((AudioStreamIn*)mInputs[index]); 1412735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 1422735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mInputs.clear(); 1432735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent closeOutputStream((AudioStreamOut*)mOutput); 144a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete [] mSndEndpoints; 145d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland if (acoustic) { 146d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland ::dlclose(acoustic); 147d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland acoustic = 0; 148d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland } 149a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mInit = false; 150a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 151a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 152a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::initCheck() 153a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 154a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return mInit ? NO_ERROR : NO_INIT; 155a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 156a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 157a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 1582735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 159a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 1602735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent { // scope for the lock 1612735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent Mutex::Autolock lock(mLock); 162a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1632735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent // only one output stream allowed 1642735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (mOutput) { 1652735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (status) { 1662735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *status = INVALID_OPERATION; 1672735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 1682735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return 0; 1697510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 170a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1712735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent // create new output stream 1722735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 1732735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status_t lStatus = out->set(this, devices, format, channels, sampleRate); 1742735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (status) { 1752735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *status = lStatus; 1762735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 1772735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (lStatus == NO_ERROR) { 1782735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mOutput = out; 1792735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 1802735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent delete out; 1812735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 182a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 183a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return mOutput; 184a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 185a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1862735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurentvoid AudioHardware::closeOutputStream(AudioStreamOut* out) { 187a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 1882735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (mOutput == 0 || mOutput != out) { 1893fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Attempt to close invalid output stream"); 190a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 191a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland else { 1922735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent delete mOutput; 193a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mOutput = 0; 194a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 195a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 196a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 197a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioStreamIn* AudioHardware::openInputStream( 1982735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 1992735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioSystem::audio_in_acoustics acoustic_flags) 200a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 2019e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks // check for valid input source 2022735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 2039e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks return 0; 2049e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks } 2059e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks 2067510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.lock(); 207a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 208a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 2092735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); 2107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status) { 2117510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project *status = lStatus; 2127510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 2137510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (lStatus != NO_ERROR) { 2147510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.unlock(); 215a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete in; 216a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return 0; 217a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 218a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2192735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mInputs.add(in); 2207510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.unlock(); 2217510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 2222735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return in; 223a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 224a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2252735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurentvoid AudioHardware::closeInputStream(AudioStreamIn* in) { 226a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 2272735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 2282735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); 2292735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (index < 0) { 2303fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Attempt to close invalid input stream"); 2312735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 2322735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mLock.unlock(); 2332735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent delete mInputs[index]; 2342735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mLock.lock(); 2352735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mInputs.removeAt(index); 236a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 237a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 238a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 23963ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurentstatus_t AudioHardware::setMode(int mode) 24063ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent{ 24163ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent status_t status = AudioHardwareBase::setMode(mode); 24263ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent if (status == NO_ERROR) { 24363ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent // make sure that doAudioRouteOrMute() is called by doRouting() 24463ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent // even if the new device selected is the same as current one. 24511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent clearCurDevice(); 24663ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent } 24763ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent return status; 24863ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent} 24963ca66ea9da5ea61806ee547f3aa1c498ac235feEric Laurent 2507510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectbool AudioHardware::checkOutputStandby() 251a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 2527510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mOutput) 2537510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!mOutput->checkStandby()) 2547510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return false; 255a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2567510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return true; 257a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 258a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 259a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setMicMute(bool state) 260a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 261a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 262a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return setMicMute_nosync(state); 263a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 264a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 265a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// always call with mutex held 266a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setMicMute_nosync(bool state) 267a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 268a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mMicMute != state) { 269a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mMicMute = state; 270a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return doAudioRouteOrMute(SND_DEVICE_CURRENT); 271a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 272a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 273a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 274a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 275a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 276a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 277a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland *state = mMicMute; 278a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 279a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 280a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2812735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurentstatus_t AudioHardware::setParameters(const String8& keyValuePairs) 282a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 2832735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioParameter param = AudioParameter(keyValuePairs); 2842735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 value; 2852735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 key; 286a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const char BT_NREC_KEY[] = "bt_headset_nrec"; 287a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const char BT_NAME_KEY[] = "bt_headset_name"; 288a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const char BT_NREC_VALUE_ON[] = "on"; 289a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2902735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 29122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("setParameters() %s", keyValuePairs.string()); 2922735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 2932735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (keyValuePairs.length() == 0) return BAD_VALUE; 2942735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 2952735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent key = String8(BT_NREC_KEY); 2962735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.get(key, value) == NO_ERROR) { 2972735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (value == BT_NREC_VALUE_ON) { 298a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mBluetoothNrec = true; 299a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 300a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mBluetoothNrec = false; 3015a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Turning noise reduction and echo cancellation off for BT " 302a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland "headset"); 303a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 3042735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 3052735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent key = String8(BT_NAME_KEY); 3062735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.get(key, value) == NO_ERROR) { 307a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mBluetoothId = 0; 3087510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project for (int i = 0; i < mNumSndEndpoints; i++) { 3092735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (!strcasecmp(value.string(), mSndEndpoints[i].name)) { 3107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mBluetoothId = mSndEndpoints[i].id; 3115a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Using custom acoustic parameters for %s", value.string()); 312a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland break; 313a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 314a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 315a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mBluetoothId == 0) { 3165a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Using default acoustic parameters " 3172735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent "(%s not in acoustic database)", value.string()); 31811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent doRouting(); 319a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 320a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 321a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 322a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 3232735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 3242735e3b55bdaf33cfd0dbaa1b914231243933e92Eric LaurentString8 AudioHardware::getParameters(const String8& keys) 3252735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent{ 326ba77ed6e3c6006d2797867f14ffd01e99cafc03bEric Laurent AudioParameter param = AudioParameter(keys); 327ba77ed6e3c6006d2797867f14ffd01e99cafc03bEric Laurent return param.toString(); 3282735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent} 3292735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 3302735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 3317510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatic unsigned calculate_audpre_table_index(unsigned index) 332a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 3337510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project switch (index) { 3347510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 48000: return SAMP_RATE_INDX_48000; 3357510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 44100: return SAMP_RATE_INDX_44100; 3367510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 32000: return SAMP_RATE_INDX_32000; 3377510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 24000: return SAMP_RATE_INDX_24000; 3387510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 22050: return SAMP_RATE_INDX_22050; 3397510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 16000: return SAMP_RATE_INDX_16000; 3407510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 12000: return SAMP_RATE_INDX_12000; 3417510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 11025: return SAMP_RATE_INDX_11025; 3427510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 8000: return SAMP_RATE_INDX_8000; 3437510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project default: return -1; 344a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 345a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 3467510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 347a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 3487510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (format != AudioSystem::PCM_16_BIT) { 3493fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("getInputBufferSize bad format: %d", format); 3507510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 351a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 3527510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (channelCount < 1 || channelCount > 2) { 3533fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("getInputBufferSize bad channel count: %d", channelCount); 3547510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 355a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 356a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 3577510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 2048*channelCount; 358a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 359a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 360a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatic status_t set_volume_rpc(uint32_t device, 361a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint32_t method, 362a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint32_t volume) 363a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 364a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int fd; 365a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#if LOG_SND_RPC 366f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 367a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#endif 368a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 369a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (device == -1UL) return NO_ERROR; 370a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 371a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland fd = open("/dev/msm_snd", O_RDWR); 372a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (fd < 0) { 373c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Can not open snd device"); 374a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EPERM; 375a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 376a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland /* rpc_snd_set_volume( 377a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * device, # Any hardware device enum, including 378a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # SND_DEVICE_CURRENT 379a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * method, # must be SND_METHOD_VOICE to do anything useful 380a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * volume, # integer volume level, in range [0,5]. 381a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # note that 0 is audible (not quite muted) 382a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * ) 383a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * rpc_snd_set_volume only works for in-call sound volume. 384a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland */ 3857510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project struct msm_snd_volume_config args; 3867510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project args.device = device; 3877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project args.method = method; 3887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project args.volume = volume; 389a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 3907510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 391c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("snd_set_volume error."); 3927510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project close(fd); 3937510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return -EIO; 3947510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 3957510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project close(fd); 3967510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return NO_ERROR; 397a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 398a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 399a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 400a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 401a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (v < 0.0) { 4023fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 403a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland v = 0.0; 404a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (v > 1.0) { 4053fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 406a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland v = 1.0; 407a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 408a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 409a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int vol = lrint(v * 5.0); 410f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("setVoiceVolume(%f)\n", v); 4115a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 412a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 413d066973de83218a24c773e5de04d10ed2d730873Eric Laurent Mutex::Autolock lock(mLock); 414a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 415a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 416a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 417a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 418a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 419a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 420a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 421a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int vol = ceil(v * 5.0); 4225a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Set master volume to %d.\n", vol); 4232735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent /* 424a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 425a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 426a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 427a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 4282735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent */ 429a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // We return an error code here to let the audioflinger do in-software 430a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // volume on top of the maximum volume that we set through the SND API. 431a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // return error - software mixer will handle it 432a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -1; 433a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 434a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 435a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatic status_t do_route_audio_rpc(uint32_t device, 436a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland bool ear_mute, bool mic_mute) 437a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 438a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (device == -1UL) 439a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 440a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 441a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int fd; 442a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#if LOG_SND_RPC 443f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 444a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#endif 445a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 446a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland fd = open("/dev/msm_snd", O_RDWR); 447a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (fd < 0) { 448c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Can not open snd device"); 449a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EPERM; 450a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 451a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // RPC call to switch audio path 452a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland /* rpc_snd_set_device( 453a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * device, # Hardware device enum to use 454a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * ear_mute, # Set mute for outgoing voice audio 455a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # this should only be unmuted when in-call 456a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * mic_mute, # Set mute for incoming voice audio 457a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # this should only be unmuted when in-call or 458a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # recording. 459a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * ) 460a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland */ 4613ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev struct msm_snd_device_config args; 462a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland args.device = device; 463a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 464a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 465a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 466a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 467c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("snd_set_device error."); 468a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland close(fd); 469a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EIO; 470a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 471a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 472a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland close(fd); 473a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 474a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 475a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 476a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// always call with mutex held 477a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::doAudioRouteOrMute(uint32_t device) 478a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 47916327daa90dffd97f03d24c59ec0a4d38aa94b90Eric Laurent if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { 480a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mBluetoothId) { 481a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland device = mBluetoothId; 482a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (!mBluetoothNrec) { 483a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland device = SND_DEVICE_BT_EC_OFF; 484a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 485a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 48622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("doAudioRouteOrMute() device %x, mMode %d, mMicMute %d", device, mMode, mMicMute); 487a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return do_route_audio_rpc(device, 4887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mMode != AudioSystem::MODE_IN_CALL, mMicMute); 489a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 490a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 49111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurentstatus_t AudioHardware::doRouting() 492a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 493d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland /* currently this code doesn't work without the htc libacoustic */ 494d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland if (!acoustic) 495d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland return 0; 496d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland 497a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 4982735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t outputDevices = mOutput->devices(); 4992735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status_t ret = NO_ERROR; 5007510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*msm72xx_enable_audpp)(int); 5017510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp"); 5022735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 50311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent AudioStreamInMSM72xx *input = getActiveInput_l(); 50411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent uint32_t inputDevice = (input == NULL) ? 0 : input->devices(); 5052735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent int sndDevice = -1; 5062735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 50711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (inputDevice != 0) { 5085a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("do input routing device %x\n", inputDevice); 50911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 5105a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth PCM\n"); 51111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_BT; 51211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 51311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 51411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 5155a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset and Speaker\n"); 51611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 51711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 51811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else { 5195a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset\n"); 52011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HEADSET; 52111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 52211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else { 52311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 5245a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Speakerphone\n"); 52511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_SPEAKER; 52611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 5272735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 5285a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Handset\n"); 52911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HANDSET; 5302735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5312735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5322735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 53311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // if inputDevice == 0, restore output routing 5342735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 5352735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (sndDevice == -1) { 5362735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (outputDevices & (outputDevices - 1)) { 5372735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 5383fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Hardware does not support requested route combination (%#X)," 5392735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent " picking closest possible route...", outputDevices); 5402735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5412735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5422735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 543dd65e38951ed174f9d3d34886795438440f7eea0Eric Laurent if (outputDevices & 544dd65e38951ed174f9d3d34886795438440f7eea0Eric Laurent (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 5455a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth PCM\n"); 5462735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_BT; 54716327daa90dffd97f03d24c59ec0a4d38aa94b90Eric Laurent } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 5485a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth PCM\n"); 54916327daa90dffd97f03d24c59ec0a4d38aa94b90Eric Laurent sndDevice = SND_DEVICE_CARKIT; 5502735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 5512735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 5525a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset and Speaker\n"); 5532735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 5542735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 5552735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 5562735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 5575a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 5582735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 5592735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 5602735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 5615a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 5622735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_NO_MIC_HEADSET; 5632735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5642735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 5655a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset\n"); 5662735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_HEADSET; 5672735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 5685a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Speakerphone\n"); 5692735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_SPEAKER; 5702735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 5712735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 5725a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Handset\n"); 5732735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent sndDevice = SND_DEVICE_HANDSET; 5742735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5752735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5762735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 5772735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (sndDevice != -1 && sndDevice != mCurSndDevice) { 5782735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent ret = doAudioRouteOrMute(sndDevice); 5792735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if ((*msm72xx_enable_audpp) == 0 ) { 580c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open msm72xx_enable_audpp()"); 5812735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 5822735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent msm72xx_enable_audpp(audProcess); 5832735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 5842735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mCurSndDevice = sndDevice; 585a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 586a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 587a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return ret; 588a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 589a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 590a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::checkMicMute() 591a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 592a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 593a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mMode != AudioSystem::MODE_IN_CALL) { 594a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland setMicMute_nosync(true); 595a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 5967510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 597a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 598a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 599a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 600a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 601a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 602a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const size_t SIZE = 256; 603a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland char buffer[SIZE]; 604a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland String8 result; 605a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append("AudioHardware::dumpInternals\n"); 606a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 607a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 608a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 609a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 610a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 611a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 612a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 613a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 614a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::write(fd, result.string(), result.size()); 615a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 616a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 617a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 618a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 619a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 620a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland dumpInternals(fd, args); 6212735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent for (size_t index = 0; index < mInputs.size(); index++) { 6222735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mInputs[index]->dump(fd, args); 623a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 6242735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 625a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mOutput) { 626a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mOutput->dump(fd, args); 627a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 628a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 629a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 630a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 6312735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurentuint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 6327510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project{ 6332735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t i; 6342735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t prevDelta; 6352735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t delta; 6362735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 6372735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 6382735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent delta = abs(sampleRate - inputSamplingRates[i]); 6392735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (delta > prevDelta) break; 6407510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 6412735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent // i is always > 0 here 6422735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return inputSamplingRates[i-1]; 6437510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project} 6447510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 64511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent// getActiveInput_l() must be called with mLock held 64611c6a166fa684a2e44d22a142aad106f74a9409fEric LaurentAudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l() 64711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent{ 64811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 64911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // return first input found not being in standby mode 65011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // as only one input can be in this state 65111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (mInputs[i]->state() > AudioStreamInMSM72xx::AUDIO_INPUT_CLOSED) { 65211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent return mInputs[i]; 65311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 65411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 65511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 65611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent return NULL; 65711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent} 658a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 659a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 660a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 6612735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 662a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 663a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 664a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 665a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::set( 6662735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 667a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 6682735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent int lFormat = pFormat ? *pFormat : 0; 6692735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t lChannels = pChannels ? *pChannels : 0; 6702735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t lRate = pRate ? *pRate : 0; 6712735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 6722735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mHardware = hw; 6732735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 674a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // fix up defaults 6752735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (lFormat == 0) lFormat = format(); 6762735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (lChannels == 0) lChannels = channels(); 6772735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (lRate == 0) lRate = sampleRate(); 678a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 679a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // check values 6802735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if ((lFormat != format()) || 6812735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent (lChannels != channels()) || 6822735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent (lRate != sampleRate())) { 6832735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pFormat) *pFormat = format(); 6842735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pChannels) *pChannels = channels(); 6852735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pRate) *pRate = sampleRate(); 686a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return BAD_VALUE; 6872735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 688a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 6892735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pFormat) *pFormat = lFormat; 6902735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pChannels) *pChannels = lChannels; 6912735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pRate) *pRate = lRate; 6922735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 6932735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mDevices = devices; 694a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 695a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 696a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 697a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 698a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 699a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 70034a989e873c51c4fbef5beaf068283e82f41ff29Eric Laurent if (mFd >= 0) close(mFd); 701a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 702a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 703a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 704a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 705f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block // ALOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 706a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t status = NO_INIT; 707a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland size_t count = bytes; 708a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 709a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 7107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mStandby) { 711a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 712a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // open driver 71322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("open driver"); 714a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 715a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 716c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 717a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 718a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 719a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = status; 720a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 721a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // configuration 72222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get config"); 723a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland struct msm_audio_config config; 724a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 725a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 726c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot read config"); 727a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 728a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 729a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 73022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set config"); 7312735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent config.channel_count = AudioSystem::popCount(channels()); 732a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.sample_rate = sampleRate(); 733a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.buffer_size = bufferSize(); 7347510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 735a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.codec_type = CODEC_TYPE_PCM; 736a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 737a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 738c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot set config"); 739a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 740a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 741a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 74222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_size: %u", config.buffer_size); 74322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_count: %u", config.buffer_count); 74422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("channel_count: %u", config.channel_count); 74522f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("sample_rate: %u", config.sample_rate); 746a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 747a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // fill 2 buffers before AUDIO_START 7487510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mStartCount = AUDIO_HW_NUM_OUT_BUF; 7497510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mStandby = false; 750a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 751a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 752a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland while (count) { 753a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ssize_t written = ::write(mFd, p, count); 754a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (written >= 0) { 755a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland count -= written; 756a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland p += written; 757a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 758a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (errno != EAGAIN) return written; 759a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mRetryCount++; 7603fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("EAGAIN - retry"); 761a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 762a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 763a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 764a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // start audio after we fill 2 buffers 765a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mStartCount) { 766a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (--mStartCount == 0) { 767a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ioctl(mFd, AUDIO_START, 0); 768a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 769a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 770a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return bytes; 771a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 772a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandError: 77334a989e873c51c4fbef5beaf068283e82f41ff29Eric Laurent if (mFd >= 0) { 774a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::close(mFd); 775a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = -1; 776a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 777a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // Simulate audio output timing in case of error 7787510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project usleep(bytes * 1000000 / frameSize() / sampleRate()); 779a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 780a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return status; 781a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 782a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 783a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::standby() 784a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 785a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t status = NO_ERROR; 78634a989e873c51c4fbef5beaf068283e82f41ff29Eric Laurent if (!mStandby && mFd >= 0) { 787a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::close(mFd); 788a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = -1; 789a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 7907510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mStandby = true; 791a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return status; 792a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 793a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 794a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 795a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 796a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const size_t SIZE = 256; 797a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland char buffer[SIZE]; 798a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland String8 result; 799a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append("AudioStreamOutMSM72xx::dump\n"); 800a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 801a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 802a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 803a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 8042735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 805a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 806a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 807a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 808a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 809a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 810a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 811a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 812a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 813a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 814a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 815a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 8167510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 8177510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project result.append(buffer); 818a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::write(fd, result.string(), result.size()); 819a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 820a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 821a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 8227510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectbool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 8237510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project{ 8247510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return mStandby; 8257510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project} 8267510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 8272735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8282735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurentstatus_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 8292735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent{ 8302735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioParameter param = AudioParameter(keyValuePairs); 8312735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 key = String8(AudioParameter::keyRouting); 8322735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status_t status = NO_ERROR; 8332735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent int device; 83422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 8352735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8362735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.getInt(key, device) == NO_ERROR) { 8372735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mDevices = device; 83822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set output routing %x", mDevices); 83911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent status = mHardware->doRouting(); 8402735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent param.remove(key); 8412735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 8422735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8432735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.size()) { 8442735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status = BAD_VALUE; 8452735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 8462735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return status; 8472735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent} 8482735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8492735e3b55bdaf33cfd0dbaa1b914231243933e92Eric LaurentString8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 8502735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent{ 8512735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioParameter param = AudioParameter(keys); 8522735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 value; 8532735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 key = String8(AudioParameter::keyRouting); 8542735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8552735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.get(key, value) == NO_ERROR) { 85622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get routing %x", mDevices); 8572735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent param.addInt(key, (int)mDevices); 8582735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 8592735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 86022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 8612735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return param.toString(); 8622735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent} 8632735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8643b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurentstatus_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames) 8653b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent{ 8663b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent //TODO: enable when supported by driver 8673b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent return INVALID_OPERATION; 8683b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent} 8692735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 870a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 871a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 872a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 8737510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 8742735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 8757510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 8762735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 877a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 878a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 879a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 880a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::set( 8812735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 8827510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project AudioSystem::audio_in_acoustics acoustic_flags) 883a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 8842735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 8852735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pFormat = AUDIO_HW_IN_FORMAT; 8862735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return BAD_VALUE; 8872735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 8882735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pRate == 0) { 8892735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return BAD_VALUE; 8902735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 8912735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent uint32_t rate = hw->getInputSampleRate(*pRate); 8922735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (rate != *pRate) { 8932735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pRate = rate; 8942735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return BAD_VALUE; 8952735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 8962735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 8972735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 8982735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 8992735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pChannels = AUDIO_HW_IN_CHANNELS; 9002735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return BAD_VALUE; 9012735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 9022735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 9032735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mHardware = hw; 9042735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 90522f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 906a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mFd >= 0) { 907c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Audio record already open"); 908a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EPERM; 909a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 910a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 911a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // open audio input device 912a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 913a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 914c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 915a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 916a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 917a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = status; 918a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 919a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // configuration 92022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get config"); 921a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland struct msm_audio_config config; 922a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 923a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 924c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot read config"); 925a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 926a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 927a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 92822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set config"); 9292735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent config.channel_count = AudioSystem::popCount(*pChannels); 9302735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent config.sample_rate = *pRate; 931a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.buffer_size = bufferSize(); 932a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.buffer_count = 2; 933a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.codec_type = CODEC_TYPE_PCM; 934a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 935a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 936c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot set config"); 9372735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 9382735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (config.channel_count == 1) { 9392735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pChannels = AudioSystem::CHANNEL_IN_MONO; 9402735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 9412735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pChannels = AudioSystem::CHANNEL_IN_STEREO; 9422735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 9432735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent *pRate = config.sample_rate; 9442735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 945a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 946a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 947a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 94822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("confirm config"); 949a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 950a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 951c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot read config"); 952a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 953a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 95422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_size: %u", config.buffer_size); 95522f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_count: %u", config.buffer_count); 95622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("channel_count: %u", config.channel_count); 95722f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("sample_rate: %u", config.sample_rate); 958a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 9592735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mDevices = devices; 9602735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mFormat = AUDIO_HW_IN_FORMAT; 9612735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mChannels = *pChannels; 9627510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mSampleRate = config.sample_rate; 9637510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mBufferSize = config.buffer_size; 9647510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 9652735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent //mHardware->setMicMute_nosync(false); 9667510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mState = AUDIO_INPUT_OPENED; 967d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland 968d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland if (!acoustic) 969d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland return NO_ERROR; 970d498a9ce9863bd979d3403473568c6e1e38b7daeBrian Swetland 9712735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent audpre_index = calculate_audpre_table_index(mSampleRate); 9727510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 973f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 9747510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 9757510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project /** 9767510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project * If audio-preprocessing failed, we should not block record. 9777510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project */ 9787510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*msm72xx_set_audpre_params)(int, int); 9797510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 9807510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 9817510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status < 0) 982c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot set audpre parameters"); 9837510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 9847510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*msm72xx_enable_audpre)(int, int, int); 9857510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 9867510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mAcoustics = acoustic_flags; 9877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 9887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status < 0) 989c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot enable audpre"); 9907510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 991a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 992a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 993a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandError: 99434a989e873c51c4fbef5beaf068283e82f41ff29Eric Laurent if (mFd >= 0) { 995a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::close(mFd); 996a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = -1; 997a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 998a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return status; 999a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 1000a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1001a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 1002a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 100322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx destructor"); 10042735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent standby(); 1005a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 1006a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1007a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 1008a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 100922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 10107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!mHardware) return -1; 1011a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1012a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland size_t count = bytes; 1013a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint8_t* p = static_cast<uint8_t*>(buffer); 1014a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 10157510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mState < AUDIO_INPUT_OPENED) { 1016d066973de83218a24c773e5de04d10ed2d730873Eric Laurent Mutex::Autolock lock(mHardware->mLock); 10172735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 10187510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return -1; 10197510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 10207510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 10212735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 10227510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mState < AUDIO_INPUT_STARTED) { 102311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mState = AUDIO_INPUT_STARTED; 102411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // force routing to input device 102511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mHardware->clearCurDevice(); 102611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mHardware->doRouting(); 1027a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (ioctl(mFd, AUDIO_START, 0)) { 1028c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Error starting record"); 102911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent standby(); 1030a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -1; 1031a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 1032a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 1033a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1034a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland while (count) { 1035a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ssize_t bytesRead = ::read(mFd, buffer, count); 1036a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (bytesRead >= 0) { 1037a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland count -= bytesRead; 1038a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland p += bytesRead; 1039a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 1040a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (errno != EAGAIN) return bytesRead; 1041a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mRetryCount++; 10423fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("EAGAIN - retrying"); 1043a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 1044a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 1045a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return bytes; 1046a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 1047a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 10487510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatus_t AudioHardware::AudioStreamInMSM72xx::standby() 10497510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project{ 10507510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mState > AUDIO_INPUT_CLOSED) { 105134a989e873c51c4fbef5beaf068283e82f41ff29Eric Laurent if (mFd >= 0) { 10527510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ::close(mFd); 10537510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mFd = -1; 10547510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 10557510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mState = AUDIO_INPUT_CLOSED; 10567510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 105711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (!mHardware) return -1; 105811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // restore output routing if necessary 105911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mHardware->clearCurDevice(); 106011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mHardware->doRouting(); 10617510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return NO_ERROR; 10627510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project} 10637510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 1064a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 1065a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 1066a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const size_t SIZE = 256; 1067a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland char buffer[SIZE]; 1068a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland String8 result; 1069a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append("AudioStreamInMSM72xx::dump\n"); 1070a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 1071a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 1072a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 1073a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 10742735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 1075a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 1076a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 1077a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 1078a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 1079a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 1080a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 1081a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 10827510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snprintf(buffer, SIZE, "\tmState: %d\n", mState); 1083a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 1084a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 1085a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 1086a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::write(fd, result.string(), result.size()); 1087a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 1088a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 1089a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 10902735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurentstatus_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 10912735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent{ 10922735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioParameter param = AudioParameter(keyValuePairs); 10932735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 key = String8(AudioParameter::keyRouting); 10942735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status_t status = NO_ERROR; 10952735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent int device; 109622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 10972735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 10982735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.getInt(key, device) == NO_ERROR) { 109922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set input routing %x", device); 11002735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (device & (device - 1)) { 11012735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status = BAD_VALUE; 11022735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } else { 11032735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent mDevices = device; 110411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent status = mHardware->doRouting(); 11052735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 11062735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent param.remove(key); 11072735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 11082735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 11092735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.size()) { 11102735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent status = BAD_VALUE; 11112735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 11122735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return status; 11132735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent} 11142735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 11152735e3b55bdaf33cfd0dbaa1b914231243933e92Eric LaurentString8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 11162735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent{ 11172735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent AudioParameter param = AudioParameter(keys); 11182735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 value; 11192735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent String8 key = String8(AudioParameter::keyRouting); 11202735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 11212735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent if (param.get(key, value) == NO_ERROR) { 112222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get routing %x", mDevices); 11232735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent param.addInt(key, (int)mDevices); 11242735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent } 11252735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 112622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 11272735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent return param.toString(); 11282735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent} 11292735e3b55bdaf33cfd0dbaa1b914231243933e92Eric Laurent 1130a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 1131a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1132a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 1133a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return new AudioHardware(); 1134a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 1135a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 1136a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland}; // namespace android 1137