165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland/* 265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** Copyright 2008, The Android Open-Source Project 365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** 465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** Licensed under the Apache License, Version 2.0 (the "License"); 565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** you may not use this file except in compliance with the License. 665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** You may obtain a copy of the License at 765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** 865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** http://www.apache.org/licenses/LICENSE-2.0 965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** 1065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** Unless required by applicable law or agreed to in writing, software 1165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** distributed under the License is distributed on an "AS IS" BASIS, 1265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** See the License for the specific language governing permissions and 1465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland** limitations under the License. 1565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland*/ 1665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 1765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <math.h> 1865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 1965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland//#define LOG_NDEBUG 0 2065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#define LOG_TAG "AudioHardware" 2165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 2265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <utils/Log.h> 2365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <utils/String8.h> 2465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland//#include <hardware_legacy/power.h> 2565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 2665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <stdio.h> 2765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <unistd.h> 2865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <sys/ioctl.h> 2965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <sys/types.h> 3065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <sys/stat.h> 3165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <dlfcn.h> 3265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <fcntl.h> 3365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 3465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include "AudioHardware.h" 3565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <media/AudioRecord.h> 3665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 3765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandextern "C" { 3865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include "msm_audio.h" 3965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 4065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 4165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 4265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandnamespace android { 4365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// ---------------------------------------------------------------------------- 4465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 4565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandAudioHardware::AudioHardware() : 4665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mInit(false), mMicMute(true), mOutput(0) 4765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 4865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mInit = true; 4965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 5065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 5165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandAudioHardware::~AudioHardware() 5265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 5365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland closeOutputStream((AudioStreamOut*)mOutput); 5465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mInit = false; 5565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 5665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 5765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::initCheck() 5865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 5965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return mInit ? NO_ERROR : NO_INIT; 6065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 6165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 6265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 6365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 6465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 6565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland { // scope for the lock 6665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland Mutex::Autolock lock(mLock); 6765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 6865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // only one output stream allowed 6965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (mOutput) { 7065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (status) { 7165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *status = INVALID_OPERATION; 7265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 7365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return 0; 7465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 7565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 7665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland AudioStreamOutQ5V2* out = new AudioStreamOutQ5V2(); 7765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 7865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status_t rc = out->set(this, devices, format, channels, sampleRate); 7965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (rc) { 8065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *status = rc; 8165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 8265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (rc == NO_ERROR) { 8365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mOutput = out; 8465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } else { 8565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland delete out; 8665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 8765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 8865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return mOutput; 8965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 9065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 9165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandvoid AudioHardware::closeOutputStream(AudioStreamOut* out) { 9265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland Mutex::Autolock lock(mLock); 9365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (mOutput == 0 || mOutput != out) { 9465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGW("Attempt to close invalid output stream"); 9565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 9665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland else { 9765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland delete mOutput; 9865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mOutput = 0; 9965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 10065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 10165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 10265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandAudioStreamIn* AudioHardware::openInputStream( 10365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 10465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 10565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 10665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return 0; 10765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 10865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 10965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandvoid AudioHardware::closeInputStream(AudioStreamIn* in) { 11065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 11165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 11265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::setMode(int mode) 11365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 11465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 11565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 11665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 11765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::setMicMute(bool state) 11865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 11965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 12065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 12165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 12265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 12365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 12465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *state = mMicMute; 12565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 12665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 12765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 12865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::setParameters(const String8& keyValuePairs) 12965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 13065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 13165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 13265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 13365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandString8 AudioHardware::getParameters(const String8& keys) 13465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 13565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland AudioParameter request = AudioParameter(keys); 13665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland AudioParameter reply = AudioParameter(); 13765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 13865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("getParameters() %s", keys.string()); 13965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 14065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return reply.toString(); 14165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 14265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 14365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 14465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 14565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return 4096; 14665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 14765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 14865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 14965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 15065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 15165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 15265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 15365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 15465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 15565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGI("Set master volume to %f.\n", v); 15665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // We return an error code here to let the audioflinger do in-software 15765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // volume on top of the maximum volume that we set through the SND API. 15865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // return error - software mixer will handle it 15965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return -1; 16065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 16165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 16265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 16365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 16465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 16565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 16665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 16765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandAudioHardware::AudioStreamOutQ5V2::AudioStreamOutQ5V2() : 16865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), 16965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mDevices(0), mChannels(AUDIO_HW_OUT_CHANNELS), mSampleRate(AUDIO_HW_OUT_SAMPLERATE), 17065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mBufferSize(AUDIO_HW_OUT_BUFSZ) 17165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 17265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 17365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 17465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::AudioStreamOutQ5V2::set( 17565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 17665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 17765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland int lFormat = pFormat ? *pFormat : 0; 17865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland uint32_t lChannels = pChannels ? *pChannels : 0; 17965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland uint32_t lRate = pRate ? *pRate : 0; 18065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 18165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mHardware = hw; 18265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mDevices = devices; 18365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 18465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // fix up defaults 18565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (lFormat == 0) lFormat = format(); 18665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (lChannels == 0) lChannels = channels(); 18765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (lRate == 0) lRate = sampleRate(); 18865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 18965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // check values 19065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if ((lFormat != format()) || 19165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland (lChannels != channels()) || 19265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland (lRate != sampleRate())) { 19365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (pFormat) *pFormat = format(); 19465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (pChannels) *pChannels = channels(); 19565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (pRate) *pRate = sampleRate(); 19665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return BAD_VALUE; 19765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 19865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 19965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (pFormat) *pFormat = lFormat; 20065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (pChannels) *pChannels = lChannels; 20165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (pRate) *pRate = lRate; 20265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 20365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mChannels = lChannels; 20465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mSampleRate = lRate; 20565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mBufferSize = 4096; 20665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 20765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 20865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 20965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 21065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandAudioHardware::AudioStreamOutQ5V2::~AudioStreamOutQ5V2() 21165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 21265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland standby(); 21365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 21465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 21565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandssize_t AudioHardware::AudioStreamOutQ5V2::write(const void* buffer, size_t bytes) 21665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 21765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // LOGD("AudioStreamOutQ5V2::write(%p, %u)", buffer, bytes); 21865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status_t status = NO_INIT; 21965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland size_t count = bytes; 22065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 22165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 22265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (mStandby) { 22365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("open pcm_out driver"); 22465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 22565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (status < 0) { 22665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 22765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland goto Error; 22865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 22965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mFd = status; 23065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 23165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // configuration 23265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("get config"); 23365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland struct msm_audio_config config; 23465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 23565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (status < 0) { 23665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGE("Cannot read pcm_out config"); 23765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland goto Error; 23865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 23965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 24065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("set pcm_out config"); 24165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland config.channel_count = AudioSystem::popCount(channels()); 24265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland config.sample_rate = mSampleRate; 24365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland config.buffer_size = mBufferSize; 24465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 24565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// config.codec_type = CODEC_TYPE_PCM; 24665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 24765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (status < 0) { 24865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGE("Cannot set config"); 24965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland goto Error; 25065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 25165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 25265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("buffer_size: %u", config.buffer_size); 25365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("buffer_count: %u", config.buffer_count); 25465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("channel_count: %u", config.channel_count); 25565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("sample_rate: %u", config.sample_rate); 25665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 25765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#if 0 25865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status = ioctl(mFd, AUDIO_START, &acdb_id); 25965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (status < 0) { 26065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGE("Cannot start pcm playback"); 26165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland goto Error; 26265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 26365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 26465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status = ioctl(mFd, AUDIO_SET_VOLUME, &stream_volume); 26565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (status < 0) { 26665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGE("Cannot start pcm playback"); 26765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland goto Error; 26865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 26965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#endif 27065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mStandby = false; 27165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 27265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 27365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland while (count) { 27465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland ssize_t written = ::write(mFd, p, count); 27565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (written >= 0) { 27665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland count -= written; 27765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland p += written; 27865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } else { 27965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (errno != EAGAIN) return written; 28065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mRetryCount++; 28165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGW("EAGAIN - retry"); 28265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 28365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 28465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 28565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return bytes; 28665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 28765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandError: 28865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (mFd >= 0) { 28965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland ::close(mFd); 29065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mFd = -1; 29165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 29265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland // Simulate audio output timing in case of error 29365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland usleep(bytes * 1000000 / frameSize() / sampleRate()); 29465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 29565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return status; 29665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 29765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 29865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::AudioStreamOutQ5V2::standby() 29965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 30065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland status_t status = NO_ERROR; 30165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland if (!mStandby && mFd >= 0) { 30265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland ::close(mFd); 30365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mFd = -1; 30465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland } 30565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland mStandby = true; 30665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGI("AudioHardware pcm playback is going to standby."); 30765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return status; 30865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 30965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 31065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::AudioStreamOutQ5V2::dump(int fd, const Vector<String16>& args) 31165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 31265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 31365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 31465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 31565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandbool AudioHardware::AudioStreamOutQ5V2::checkStandby() 31665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 31765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return mStandby; 31865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 31965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 32065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::AudioStreamOutQ5V2::setParameters(const String8& keyValuePairs) 32165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 32265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return NO_ERROR; 32365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 32465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 32565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian SwetlandString8 AudioHardware::AudioStreamOutQ5V2::getParameters(const String8& keys) 32665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 32765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland AudioParameter param = AudioParameter(keys); 32865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland LOGV("AudioStreamOutQ5V2::getParameters() %s", param.toString().string()); 32965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return param.toString(); 33065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 33165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 33265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandstatus_t AudioHardware::AudioStreamOutQ5V2::getRenderPosition(uint32_t *dspFrames) 33365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{ 33465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return INVALID_OPERATION; 33565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 33665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 33765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 33865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland return new AudioHardware(); 33965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland} 34065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland 34165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland}; // namespace android 342