AudioHardware.cpp revision 9e8b6821afad923dcc616768f7582545c90a0bc6
1a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland/* 2a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland** Copyright 2008, Google Inc. 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), 497510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mOutput(0), mInput(0), mSndEndpoints(NULL), 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_BT(-1), 54a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland SND_DEVICE_BT_EC_OFF(-1), 55a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland SND_DEVICE_HEADSET(-1), 56a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland SND_DEVICE_HEADSET_AND_SPEAKER(-1) 57a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 58a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 597510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*snd_get_num)(); 607510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*snd_get_endpoint)(int, msm_snd_endpoint *); 617510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*set_acoustic_parameters)(); 627510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 637510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project struct msm_snd_endpoint *ept; 647510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 657510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 667510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (acoustic == NULL ) { 677510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Could not open libhtc_acoustic.so"); 687510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return; 697510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 707510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 717510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 727510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if ((*set_acoustic_parameters) == 0 ) { 737510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Could not open set_acoustic_parameters()"); 743ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev return; 753ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev } 763ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev 777510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int rc = set_acoustic_parameters(); 787510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (rc < 0) { 797510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Could not set acoustic parameters to share memory: %d", rc); 807510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project// return; 817510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 827510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 837510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints"); 847510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if ((*snd_get_num) == 0 ) { 857510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Could not open snd_get_num()"); 867510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project// return; 877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 897510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mNumSndEndpoints = snd_get_num(); 907510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGD("mNumSndEndpoints = %d", mNumSndEndpoints); 917510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints]; 927510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mInit = true; 937510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGV("constructed %d SND endpoints)", mNumSndEndpoints); 947510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ept = mSndEndpoints; 957510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint"); 967510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if ((*snd_get_endpoint) == 0 ) { 977510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Could not open snd_get_endpoint()"); 987510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return; 997510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 1007510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 1017510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) { 1027510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ept->id = cnt; 1037510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snd_get_endpoint(cnt, ept); 1047510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project#define CHECK_FOR(desc) \ 1057510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!strcmp(ept->name, #desc)) { \ 1067510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project SND_DEVICE_##desc = ept->id; \ 1077510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGD("BT MATCH " #desc); \ 1087510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } else 1097510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(CURRENT) 1107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(HANDSET) 1117510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(SPEAKER) 1127510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(BT) 1137510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(BT_EC_OFF) 1147510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(HEADSET) 1157510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project CHECK_FOR(HEADSET_AND_SPEAKER) {} 116a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#undef CHECK_FOR 117a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 118a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 119a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 120a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::~AudioHardware() 121a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 122a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete mInput; 123a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete mOutput; 124a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete [] mSndEndpoints; 1257510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ::dlclose(acoustic); 126a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mInit = false; 127a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 128a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 129a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::initCheck() 130a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 131a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return mInit ? NO_ERROR : NO_INIT; 132a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 133a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 134a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 1357510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int format, int channelCount, uint32_t sampleRate, status_t *status) 136a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 137a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 138a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 139a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // only one output stream allowed 1407510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mOutput) { 1417510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status) { 1427510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project *status = INVALID_OPERATION; 1437510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 1447510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 1457510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 146a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 147a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // create new output stream 148a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 1497510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project status_t lStatus = out->set(this, format, channelCount, sampleRate); 1507510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status) { 1517510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project *status = lStatus; 1527510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 1537510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (lStatus == NO_ERROR) { 154a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mOutput = out; 155a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 156a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete out; 157a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 158a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return mOutput; 159a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 160a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 161a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandvoid AudioHardware::closeOutputStream(AudioStreamOutMSM72xx* out) { 162a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 163a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mOutput != out) { 164a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("Attempt to close invalid output stream"); 165a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 166a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland else { 167a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mOutput = 0; 168a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 169a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 170a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 171a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioStreamIn* AudioHardware::openInputStream( 1729e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks int inputSource, int format, int channelCount, uint32_t sampleRate, 1739e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks status_t *status, AudioSystem::audio_in_acoustics acoustic_flags) 174a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 1759e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks // check for valid input source 1769e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks if ((inputSource != AudioRecord::DEFAULT_INPUT) && 1779e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks (inputSource != AudioRecord::MIC_INPUT)) { 1789e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks return 0; 1799e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks } 1809e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks 1817510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.lock(); 182a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // input stream already open? 1837510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mInput) { 1847510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status) { 1857510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project *status = INVALID_OPERATION; 1867510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 1877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.unlock(); 1887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 1897510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 190a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 191a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 1927510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project status_t lStatus = in->set(this, format, channelCount, sampleRate, acoustic_flags); 1937510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status) { 1947510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project *status = lStatus; 1957510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 1967510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (lStatus != NO_ERROR) { 1977510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.unlock(); 198a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland delete in; 199a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return 0; 200a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 201a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 202a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mInput = in; 2037510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mLock.unlock(); 2047510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 205a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return mInput; 206a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 207a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2089e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks// DEPRECATED 2099e8b6821afad923dcc616768f7582545c90a0bc6Dave SparksAudioStreamIn* AudioHardware::openInputStream( 2109e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks int format, int channelCount, uint32_t sampleRate, status_t *status, 2119e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks AudioSystem::audio_in_acoustics acoustic_flags) 2129e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks{ 2139e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks return openInputStream(AudioRecord::DEFAULT_INPUT, format, channelCount, 2149e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks sampleRate, status, acoustic_flags); 2159e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks} 2169e8b6821afad923dcc616768f7582545c90a0bc6Dave Sparks 217a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandvoid AudioHardware::closeInputStream(AudioStreamInMSM72xx* in) { 218a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 219a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mInput != in) { 220a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("Attempt to close invalid input stream"); 221a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 222a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland else { 223a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mInput = 0; 224a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 225a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 226a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2277510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectbool AudioHardware::checkOutputStandby() 228a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 2297510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mOutput) 2307510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!mOutput->checkStandby()) 2317510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return false; 232a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 2337510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return true; 234a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 235a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 236a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setMicMute(bool state) 237a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 238a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 239a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return setMicMute_nosync(state); 240a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 241a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 242a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// always call with mutex held 243a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setMicMute_nosync(bool state) 244a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 245a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mMicMute != state) { 246a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mMicMute = state; 247a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return doAudioRouteOrMute(SND_DEVICE_CURRENT); 248a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 249a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 250a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 251a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 252a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 253a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 254a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland *state = mMicMute; 255a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 256a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 257a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 258a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setParameter(const char *key, const char *value) 259a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 260a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("%s key = %s value = %s\n", __FUNCTION__, key, value); 261a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 262a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (key == NULL || value == NULL) { 263a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("%s called with null argument, ignoring (key = %s, value = %s", 264a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland __FUNCTION__, key, value); 265a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return BAD_VALUE; 266a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 267a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 268a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const char BT_NREC_KEY[] = "bt_headset_nrec"; 269a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const char BT_NAME_KEY[] = "bt_headset_name"; 270a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const char BT_NREC_VALUE_ON[] = "on"; 271a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 272a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (!strncmp(key, BT_NREC_KEY, sizeof(BT_NREC_KEY))) { 273a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (!strncmp(value, BT_NREC_VALUE_ON, sizeof(BT_NREC_VALUE_ON))) { 274a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mBluetoothNrec = true; 275a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 276a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mBluetoothNrec = false; 277a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Turning noise reduction and echo cancellation off for BT " 278a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland "headset"); 279a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 280a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland doRouting(); 281a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (!strncmp(key, BT_NAME_KEY, sizeof(BT_NAME_KEY))) { 282a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mBluetoothId = 0; 2837510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project for (int i = 0; i < mNumSndEndpoints; i++) { 2847510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!strcasecmp(value, mSndEndpoints[i].name)) { 2857510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mBluetoothId = mSndEndpoints[i].id; 286a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Using custom acoustic parameters for %s", value); 287a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland break; 288a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 289a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 290a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mBluetoothId == 0) { 291a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Using default acoustic parameters " 292a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland "(%s not in acoustic database)", value); 293a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland doRouting(); 294a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 295a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 296a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 297a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 298a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 2997510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatic unsigned calculate_audpre_table_index(unsigned index) 300a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 3017510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project switch (index) { 3027510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 48000: return SAMP_RATE_INDX_48000; 3037510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 44100: return SAMP_RATE_INDX_44100; 3047510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 32000: return SAMP_RATE_INDX_32000; 3057510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 24000: return SAMP_RATE_INDX_24000; 3067510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 22050: return SAMP_RATE_INDX_22050; 3077510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 16000: return SAMP_RATE_INDX_16000; 3087510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 12000: return SAMP_RATE_INDX_12000; 3097510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 11025: return SAMP_RATE_INDX_11025; 3107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project case 8000: return SAMP_RATE_INDX_8000; 3117510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project default: return -1; 312a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 313a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 3147510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 315a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 3167510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (checkInputSampleRate(sampleRate) != NO_ERROR) { 3177510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGW("getInputBufferSize bad sampling rate: %d", sampleRate); 3187510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 319a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 3207510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (format != AudioSystem::PCM_16_BIT) { 3217510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGW("getInputBufferSize bad format: %d", format); 3227510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 323a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 3247510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (channelCount < 1 || channelCount > 2) { 3257510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGW("getInputBufferSize bad channel count: %d", channelCount); 3267510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 0; 327a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 328a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 3297510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return 2048*channelCount; 330a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 331a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 332a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatic status_t set_volume_rpc(uint32_t device, 333a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint32_t method, 334a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint32_t volume) 335a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 336a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int fd; 337a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#if LOG_SND_RPC 338a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 339a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#endif 340a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 341a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (device == -1UL) return NO_ERROR; 342a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 343a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland fd = open("/dev/msm_snd", O_RDWR); 344a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (fd < 0) { 345a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Can not open snd device"); 346a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EPERM; 347a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 348a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland /* rpc_snd_set_volume( 349a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * device, # Any hardware device enum, including 350a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # SND_DEVICE_CURRENT 351a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * method, # must be SND_METHOD_VOICE to do anything useful 352a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * volume, # integer volume level, in range [0,5]. 353a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # note that 0 is audible (not quite muted) 354a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * ) 355a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * rpc_snd_set_volume only works for in-call sound volume. 356a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland */ 3577510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project struct msm_snd_volume_config args; 3587510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project args.device = device; 3597510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project args.method = method; 3607510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project args.volume = volume; 361a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 3627510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 3637510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("snd_set_volume error."); 3647510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project close(fd); 3657510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return -EIO; 3667510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 3677510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project close(fd); 3687510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return NO_ERROR; 369a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 370a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 371a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 372a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 373a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (v < 0.0) { 374a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 375a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland v = 0.0; 376a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (v > 1.0) { 377a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 378a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland v = 1.0; 379a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 380a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 381a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int vol = lrint(v * 5.0); 382a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGD("setVoiceVolume(%f)\n", v); 383a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 384a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 385d066973de83218a24c773e5de04d10ed2d730873Eric Laurent Mutex::Autolock lock(mLock); 386a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 387a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 388a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 389a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 390a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 391a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 392a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 393a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int vol = ceil(v * 5.0); 394a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Set master volume to %d.\n", vol); 395a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 396a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 397a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 398a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 399a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // We return an error code here to let the audioflinger do in-software 400a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // volume on top of the maximum volume that we set through the SND API. 401a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // return error - software mixer will handle it 402a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -1; 403a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 404a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 405a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatic status_t do_route_audio_rpc(uint32_t device, 406a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland bool ear_mute, bool mic_mute) 407a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 408a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (device == -1UL) 409a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 410a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 411a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int fd; 412a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#if LOG_SND_RPC 413a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 414a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland#endif 415a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 416a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland fd = open("/dev/msm_snd", O_RDWR); 417a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (fd < 0) { 418a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Can not open snd device"); 419a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EPERM; 420a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 421a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // RPC call to switch audio path 422a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland /* rpc_snd_set_device( 423a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * device, # Hardware device enum to use 424a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * ear_mute, # Set mute for outgoing voice audio 425a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # this should only be unmuted when in-call 426a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * mic_mute, # Set mute for incoming voice audio 427a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # this should only be unmuted when in-call or 428a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * # recording. 429a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland * ) 430a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland */ 4313ccfb0bb4f6f8c18d5b66b5568a9aa1d969a598aIliyan Malchev struct msm_snd_device_config args; 432a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland args.device = device; 433a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 434a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 435a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 436a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 437a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("snd_set_device error."); 438a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland close(fd); 439a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EIO; 440a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 441a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 442a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland close(fd); 443a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 444a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 445a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 446a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// always call with mutex held 447a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::doAudioRouteOrMute(uint32_t device) 448a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 449a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (device == (uint32_t)SND_DEVICE_BT) { 450a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mBluetoothId) { 451a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland device = mBluetoothId; 452a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (!mBluetoothNrec) { 453a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland device = SND_DEVICE_BT_EC_OFF; 454a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 455a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 456a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return do_route_audio_rpc(device, 4577510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mMode != AudioSystem::MODE_IN_CALL, mMicMute); 458a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 459a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 460a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatic int count_bits(uint32_t vector) 461a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 462a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland int bits; 463a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland for (bits = 0; vector; bits++) { 464a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland vector &= vector - 1; 465a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 466a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return bits; 467a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 468a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 469a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::doRouting() 470a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 471a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 472a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint32_t routes = mRoutes[mMode]; 473a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (count_bits(routes) > 1) { 474a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (routes != 4757510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project (AudioSystem::ROUTE_HEADSET | AudioSystem::ROUTE_SPEAKER)) { 476a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("Hardware does not support requested route combination (%#X)," 477a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland " picking closest possible route...", routes); 478a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 479a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 4807510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*msm72xx_enable_audpp)(int); 4817510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp"); 482a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t ret = NO_ERROR; 4837510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) { 484a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Routing audio to Bluetooth PCM\n"); 485a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ret = doAudioRouteOrMute(SND_DEVICE_BT); 4867510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 487a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if ((routes & AudioSystem::ROUTE_HEADSET) && 488a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland (routes & AudioSystem::ROUTE_SPEAKER)) { 489a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Routing audio to Wired Headset and Speaker\n"); 490a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ret = doAudioRouteOrMute(SND_DEVICE_HEADSET_AND_SPEAKER); 4917510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 492a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (routes & AudioSystem::ROUTE_HEADSET) { 493a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Routing audio to Wired Headset\n"); 494a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ret = doAudioRouteOrMute(SND_DEVICE_HEADSET); 4957510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 496a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else if (routes & AudioSystem::ROUTE_SPEAKER) { 497a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Routing audio to Speakerphone\n"); 498a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ret = doAudioRouteOrMute(SND_DEVICE_SPEAKER); 4997510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 500a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 501a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGI("Routing audio to Handset\n"); 502a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ret = doAudioRouteOrMute(SND_DEVICE_HANDSET); 5037510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 504a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 505a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 506a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return ret; 507a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 508a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 509a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::checkMicMute() 510a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 511a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland Mutex::Autolock lock(mLock); 512a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mMode != AudioSystem::MODE_IN_CALL) { 513a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland setMicMute_nosync(true); 514a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 5157510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 516a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 517a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 518a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 519a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 520a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 521a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const size_t SIZE = 256; 522a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland char buffer[SIZE]; 523a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland String8 result; 524a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append("AudioHardware::dumpInternals\n"); 525a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 526a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 527a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 528a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 529a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 530a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 531a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 532a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 533a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::write(fd, result.string(), result.size()); 534a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 535a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 536a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 537a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 538a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 539a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland dumpInternals(fd, args); 540a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mInput) { 541a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mInput->dump(fd, args); 542a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 543a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mOutput) { 544a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mOutput->dump(fd, args); 545a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 546a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 547a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 548a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 5497510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatus_t AudioHardware::checkInputSampleRate(uint32_t sampleRate) 5507510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project{ 5517510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project for (uint32_t i = 0; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++) { 5527510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (sampleRate == inputSamplingRates[i]) { 5537510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return NO_ERROR; 5547510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 5557510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 5567510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return BAD_VALUE; 5577510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project} 5587510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 559a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 560a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 561a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 5627510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true) 563a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 564a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 565a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 566a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::set( 567a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland AudioHardware* hw, int format, int channels, uint32_t rate) 568a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 569a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // fix up defaults 570a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (format == 0) format = AudioSystem::PCM_16_BIT; 571a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (channels == 0) channels = channelCount(); 572a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (rate == 0) rate = sampleRate(); 573a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 574a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // check values 575a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if ((format != AudioSystem::PCM_16_BIT) || 576a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland (channels != channelCount()) || 577a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland (rate != sampleRate())) 578a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return BAD_VALUE; 579a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 580a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mHardware = hw; 581a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 582a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 583a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 584a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 585a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 586a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 5877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mFd > 0) close(mFd); 588a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mHardware->closeOutputStream(this); 589a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 590a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 591a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 592a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 593a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 594a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t status = NO_INIT; 595a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland size_t count = bytes; 596a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 597a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 5987510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mStandby) { 599a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 600a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // open driver 601a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("open driver"); 602a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 603a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 6047510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 605a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 606a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 607a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = status; 608a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 609a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // configuration 610a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("get config"); 611a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland struct msm_audio_config config; 612a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 613a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 614a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Cannot read config"); 615a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 616a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 617a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 618a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("set config"); 619a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.channel_count = channelCount(); 620a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.sample_rate = sampleRate(); 621a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.buffer_size = bufferSize(); 6227510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 623a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.codec_type = CODEC_TYPE_PCM; 624a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 625a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 626a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Cannot set config"); 627a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 628a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 629a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 630a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 631a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 632a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("channel_count: %u", config.channel_count); 633a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 634a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 635a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // fill 2 buffers before AUDIO_START 6367510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mStartCount = AUDIO_HW_NUM_OUT_BUF; 6377510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mStandby = false; 638a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 639a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 640a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland while (count) { 641a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ssize_t written = ::write(mFd, p, count); 642a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (written >= 0) { 643a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland count -= written; 644a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland p += written; 645a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 646a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (errno != EAGAIN) return written; 647a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mRetryCount++; 648a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("EAGAIN - retry"); 649a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 650a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 651a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 652a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // start audio after we fill 2 buffers 653a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mStartCount) { 654a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (--mStartCount == 0) { 655a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ioctl(mFd, AUDIO_START, 0); 656a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 657a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 658a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return bytes; 659a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 660a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandError: 661a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mFd > 0) { 662a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::close(mFd); 663a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = -1; 664a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 665a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // Simulate audio output timing in case of error 6667510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project usleep(bytes * 1000000 / frameSize() / sampleRate()); 667a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 668a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return status; 669a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 670a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 671a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::standby() 672a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 673a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t status = NO_ERROR; 6747510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!mStandby && mFd > 0) { 675a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::close(mFd); 676a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = -1; 677a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 6787510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mStandby = true; 679a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return status; 680a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 681a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 682a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 683a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 684a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const size_t SIZE = 256; 685a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland char buffer[SIZE]; 686a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland String8 result; 687a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append("AudioStreamOutMSM72xx::dump\n"); 688a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 689a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 690a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 691a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 692a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 693a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 694a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 695a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 696a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 697a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 698a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 699a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 700a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 701a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 702a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 703a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 7047510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 7057510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project result.append(buffer); 706a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::write(fd, result.string(), result.size()); 707a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 708a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 709a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 7107510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectbool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 7117510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project{ 7127510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return mStandby; 7137510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project} 7147510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 715a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 716a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 717a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 7187510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 7197510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mFormat(AUDIO_HW_IN_FORMAT), mChannelCount(AUDIO_HW_IN_CHANNELS), 7207510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 7217510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mAcoustics((AudioSystem::audio_in_acoustics)0) 722a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 723a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 724a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 725a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::set( 7267510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project AudioHardware* hw, int format, int channelCount, uint32_t sampleRate, 7277510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project AudioSystem::audio_in_acoustics acoustic_flags) 728a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 729a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", format, channelCount, sampleRate); 730a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mFd >= 0) { 731a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Audio record already open"); 732a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -EPERM; 733a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 734a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 735a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // open audio input device 736a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 737a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 7387510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 739a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 740a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 741a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = status; 742a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 743a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland // configuration 744a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("get config"); 745a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland struct msm_audio_config config; 746a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 747a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 748a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Cannot read config"); 749a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 750a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 751a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 752a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("set config"); 753a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.channel_count = channelCount; 754a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.sample_rate = sampleRate; 755a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.buffer_size = bufferSize(); 756a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.buffer_count = 2; 757a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland config.codec_type = CODEC_TYPE_PCM; 758a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 759a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 760a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Cannot set config"); 761a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 762a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 763a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 764a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("confirm config"); 765a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 766a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (status < 0) { 767a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Cannot read config"); 768a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland goto Error; 769a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 770a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 771a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 772a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("channel_count: %u", config.channel_count); 773a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 774a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 7757510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mFormat = format; 7767510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mChannelCount = config.channel_count; 7777510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mSampleRate = config.sample_rate; 7787510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mBufferSize = config.buffer_size; 7797510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 780a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mHardware = hw; 781a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mHardware->setMicMute_nosync(false); 7827510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mState = AUDIO_INPUT_OPENED; 7837510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project audpre_index = calculate_audpre_table_index(sampleRate); 7847510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 7857510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 7867510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 7877510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project /** 7887510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project * If audio-preprocessing failed, we should not block record. 7897510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project */ 7907510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*msm72xx_set_audpre_params)(int, int); 7917510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 7927510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 7937510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status < 0) 7947510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Cannot set audpre parameters"); 7957510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 7967510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project int (*msm72xx_enable_audpre)(int, int, int); 7977510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 7987510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mAcoustics = acoustic_flags; 7997510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 8007510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (status < 0) 8017510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGE("Cannot enable audpre"); 8027510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 803a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 804a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 805a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandError: 806a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (mFd > 0) { 807a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::close(mFd); 808a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mFd = -1; 809a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 810a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return status; 811a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 812a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 813a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian SwetlandAudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 814a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 8157510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project LOGV("AudioStreamInMSM72xx destructor"); 8167510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mHardware) { 8177510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project standby(); 8187510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mHardware->closeInputStream(this); 8197510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 820a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 821a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 822a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 823a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 824d066973de83218a24c773e5de04d10ed2d730873Eric Laurent LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 8257510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!mHardware) return -1; 826a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 827a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland size_t count = bytes; 828a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland uint8_t* p = static_cast<uint8_t*>(buffer); 829a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 8307510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mState < AUDIO_INPUT_OPENED) { 831d066973de83218a24c773e5de04d10ed2d730873Eric Laurent Mutex::Autolock lock(mHardware->mLock); 8327510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (set(mHardware, mFormat, mChannelCount, mSampleRate, mAcoustics) != NO_ERROR) { 8337510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return -1; 8347510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 8357510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 8367510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 8377510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mState < AUDIO_INPUT_STARTED) { 838a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (ioctl(mFd, AUDIO_START, 0)) { 839a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGE("Error starting record"); 840a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return -1; 841a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 8427510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mState = AUDIO_INPUT_STARTED; 843a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 844a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 845a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland while (count) { 846a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ssize_t bytesRead = ::read(mFd, buffer, count); 847a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (bytesRead >= 0) { 848a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland count -= bytesRead; 849a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland p += bytesRead; 850a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } else { 851a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland if (errno != EAGAIN) return bytesRead; 852a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland mRetryCount++; 853a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland LOGW("EAGAIN - retrying"); 854a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 855a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland } 856a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return bytes; 857a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 858a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 8597510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Projectstatus_t AudioHardware::AudioStreamInMSM72xx::standby() 8607510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project{ 8617510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (!mHardware) return -1; 8627510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mState > AUDIO_INPUT_CLOSED) { 8637510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project if (mFd > 0) { 8647510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project ::close(mFd); 8657510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mFd = -1; 8667510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 8677510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mHardware->checkMicMute(); 8687510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project mState = AUDIO_INPUT_CLOSED; 8697510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project } 8707510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project return NO_ERROR; 8717510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project} 8727510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project 873a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 874a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland{ 875a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland const size_t SIZE = 256; 876a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland char buffer[SIZE]; 877a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland String8 result; 878a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append("AudioStreamInMSM72xx::dump\n"); 879a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 880a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 881a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 882a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 883a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 884a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 885a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 886a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 887a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 888a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 889a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 890a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 8917510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24The Android Open Source Project snprintf(buffer, SIZE, "\tmState: %d\n", mState); 892a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 893a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 894a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland result.append(buffer); 895a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland ::write(fd, result.string(), result.size()); 896a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return NO_ERROR; 897a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 898a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 899a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland// ---------------------------------------------------------------------------- 900a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 901a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 902a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland return new AudioHardware(); 903a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland} 904a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland 905a3a947cc7e1bfaf7b5cfc85b71f602edf562836Brian Swetland}; // namespace android 906