diff options
Diffstat (limited to 'libaudio/AudioHardwareALSA.cpp')
-rwxr-xr-x | libaudio/AudioHardwareALSA.cpp | 258 |
1 files changed, 160 insertions, 98 deletions
diff --git a/libaudio/AudioHardwareALSA.cpp b/libaudio/AudioHardwareALSA.cpp index f1b23f8..98ad027 100755 --- a/libaudio/AudioHardwareALSA.cpp +++ b/libaudio/AudioHardwareALSA.cpp @@ -208,7 +208,8 @@ AudioHardwareALSA::AudioHardwareALSA() : mOutput(0), mInput(0), mSecRilLibHandle(NULL), - mRilClient(0) + mRilClient(0), + mVrModeEnabled(false) { snd_lib_error_set_handler(&ALSAErrorHandler); mMixer = new ALSAMixer; @@ -289,14 +290,6 @@ status_t AudioHardwareALSA::initCheck() return NO_INIT; } -status_t AudioHardwareALSA::standby() -{ - if (mOutput) - return mOutput->standby(); - - return NO_ERROR; -} - status_t AudioHardwareALSA::connectRILDIfRequired(void) { @@ -322,11 +315,15 @@ status_t AudioHardwareALSA::setVoiceVolume(float volume) { LOGI("### setVoiceVolume"); + AutoMutex lock(mLock); // sangsu fix : transmic volume level IPC to modem if ( (AudioSystem::MODE_IN_CALL == mMode) && (mSecRilLibHandle) && (connectRILDIfRequired() == OK) ) { - uint32_t routes = mRoutes[mMode]; + uint32_t routes = AudioSystem::ROUTE_EARPIECE; + if (mOutput != NULL) { + routes = mOutput->device(); + } int int_volume = (int)(volume * 5); LOGI("### route(%d) call volume(%f)", routes, volume); @@ -395,32 +392,40 @@ AudioHardwareALSA::openOutputStream( uint32_t *sampleRate, status_t *status) { - AutoMutex lock(mLock); + AudioStreamOutALSA *out = NULL; + status_t ret = NO_ERROR; + { + AutoMutex lock(mLock); - // only one output stream allowed - if (mOutput) { - *status = ALREADY_EXISTS; - return 0; - } + // only one output stream allowed + if (mOutput) { + ret = ALREADY_EXISTS; + goto exit; + } - LOGV("[[[[[[[[\n%s - format = %d, channels = %d, sampleRate = %d, devices = %d]]]]]]]]\n", __func__, *format, *channels, *sampleRate,devices); + LOGV("[[[[[[[[\n%s - format = %d, channels = %d, sampleRate = %d, devices = %d]]]]]]]]\n", __func__, *format, *channels, *sampleRate,devices); - AudioStreamOutALSA *out = new AudioStreamOutALSA(this); + out = new AudioStreamOutALSA(this); - *status = out->set(format, channels, sampleRate); + ret = out->set(format, channels, sampleRate); - if (*status == NO_ERROR) { - mOutput = out; + if (ret == NO_ERROR) { + mOutput = out; + } + } +exit: + if (ret == NO_ERROR) { // Some information is expected to be available immediately after // the device is open. /* Tushar - Sets the current device output here - we may set device here */ LOGI("%s] Setting ALSA device.", __func__); mOutput->setDevice(mMode, devices, PLAYBACK); /* tushar - Enable all devices as of now */ - } - else { + } else if (out) { delete out; } - + if (status) { + *status = ret; + } return mOutput; } @@ -429,16 +434,16 @@ AudioHardwareALSA::closeOutputStream(AudioStreamOut* out) { /* TODO:Tushar: May lead to segmentation fault - check*/ //delete out; - AutoMutex lock(mLock); + { + AutoMutex lock(mLock); - if (mOutput == 0 || mOutput != out) { - LOGW("Attempt to close invalid output stream"); - } - else { - delete mOutput; + if (mOutput == 0 || mOutput != out) { + LOGW("Attempt to close invalid output stream"); + return; + } mOutput = 0; } - + delete out; } @@ -451,28 +456,36 @@ AudioHardwareALSA::openInputStream( status_t *status, AudioSystem::audio_in_acoustics acoustics) { - AutoMutex lock(mLock); + AudioStreamInALSA *in = NULL; + status_t ret = NO_ERROR; + { + AutoMutex lock(mLock); - // only one input stream allowed - if (mInput) { - *status = ALREADY_EXISTS; - return 0; - } + // only one input stream allowed + if (mInput) { + ret = ALREADY_EXISTS; + goto exit; + } - AudioStreamInALSA *in = new AudioStreamInALSA(this); + in = new AudioStreamInALSA(this); - *status = in->set(format, channels, sampleRate); - if (*status == NO_ERROR) { - mInput = in; + ret = in->set(format, channels, sampleRate); + if (ret == NO_ERROR) { + mInput = in; + } + } +exit: + if (ret == NO_ERROR) { // Some information is expected to be available immediately after // the device is open. mInput->setDevice(mMode, devices, CAPTURE); /* Tushar - as per modified arch */ setMicStatus(1); - return mInput; - } - else { + } else if (in != NULL) { delete in; } + if (status) { + *status = ret; + } return mInput; } @@ -481,29 +494,39 @@ AudioHardwareALSA::closeInputStream(AudioStreamIn* in) { /* TODO:Tushar: May lead to segmentation fault - check*/ //delete in; - AutoMutex lock(mLock); + { + AutoMutex lock(mLock); - if (mInput == 0 || mInput != in) { - LOGW("Attempt to close invalid input stream"); - } else { - delete mInput; - mInput = 0; - setMicStatus(0); + if (mInput == 0 || mInput != in) { + LOGW("Attempt to close invalid input stream"); + return; + } else { + mInput = 0; + setMicStatus(0); + } } + delete in; } -status_t AudioHardwareALSA::doRouting(uint32_t device) +status_t AudioHardwareALSA::doRouting(uint32_t device, bool force) { - status_t ret; - AutoMutex lock(mLock); + return doRouting_l(device, force); +} + +status_t AudioHardwareALSA::doRouting_l(uint32_t device, bool force) +{ + status_t ret; int mode = mMode; // Prevent to changing mode on setup sequence. - LOGV("doRouting (%d)", device); + LOGV("doRouting: device %x, force %d", device, force); if (mOutput) { //device = 0; /* Tushar - temp implementation */ + if (device == AudioSystem::DEVICE_OUT_DEFAULT) { + device = mOutput->device(); + } // Setup sound path for CP clocking if ( (AudioSystem::MODE_IN_CALL == mode) && (mSecRilLibHandle) && @@ -546,7 +569,7 @@ status_t AudioHardwareALSA::doRouting(uint32_t device) } } - ret = mOutput->setDevice(mode, device, PLAYBACK); + ret = mOutput->setDevice(mode, device, PLAYBACK, force); return ret; } @@ -597,14 +620,6 @@ size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, in LOGV("getInputBufferSize() rate %d, shift %d, size %d", sampleRate, shift, size); return size; -//#if defined SEC_SWP_SOUND -// if (sampleRate == 32000 || sampleRate == 44100 || sampleRate == 48000) -// return READ_FRAME_SIZE_STANDARD; -// else -// return READ_FRAME_SIZE; -//#else /* SEC_SWP_SOUND */ -// return 320; -//#endif /* SEC_SWP_SOUND */ } uint32_t AudioHardwareALSA::checkInputSampleRate(uint32_t sampleRate) @@ -621,6 +636,53 @@ uint32_t AudioHardwareALSA::checkInputSampleRate(uint32_t sampleRate) return i-1; } +status_t AudioHardwareALSA::setMode(int mode) +{ + AutoMutex lock(mLock); + int prevMode = mMode; + status_t status = AudioHardwareBase::setMode(mode); + LOGV("setMode() : new %d, old %d", mMode, prevMode); + if (status == NO_ERROR) { + // make sure that doAudioRouteOrMute() is called by doRouting() + // when entering or exiting in call mode even if the new device + // selected is the same as current one. + if ((prevMode != AudioSystem::MODE_IN_CALL) && (mMode == AudioSystem::MODE_IN_CALL)) { + LOGV("setMode() entering call"); + doRouting_l(AudioSystem::DEVICE_OUT_DEFAULT, true); + setVoiceRecordGain_l(false); + } + if ((prevMode == AudioSystem::MODE_IN_CALL) && (mMode != AudioSystem::MODE_IN_CALL)) { + LOGV("setMode() exiting call"); + doRouting_l(AudioSystem::DEVICE_OUT_DEFAULT, true); + if (mOutput != NULL && !mOutput->isActive()) { + mOutput->close(); + } + } + } + + return status; +} + +int AudioHardwareALSA::setVoiceRecordGain(bool enable) +{ + AutoMutex lock(mLock); + return setVoiceRecordGain_l(enable); +} + +int AudioHardwareALSA::setVoiceRecordGain_l(bool enable) +{ + LOGI("[%s], enable=%d", __func__, enable); + if (enable != mVrModeEnabled && + !(enable && (mMode == AudioSystem::MODE_IN_CALL))) { + ALSAControl *alsaControl = new ALSAControl(); + status_t ret = alsaControl->set("Codec Status", enable ? 5 : 4); + delete alsaControl; + mVrModeEnabled = enable; + } + + return NO_ERROR; +} + // ---------------------------------------------------------------------------- ALSAStreamOps::ALSAStreamOps() : @@ -699,15 +761,6 @@ status_t ALSAStreamOps::set(int *pformat, uint32_t ALSAStreamOps::sampleRate() const { -// unsigned int rate; -// int err; -// -// if (! mHandle) -// return NO_INIT; -// -// return snd_pcm_hw_params_get_rate(mHardwareParams, &rate, 0) < 0 -// ? 0 : static_cast<uint32_t>(rate); - return mDefaults->sampleRate; } @@ -790,9 +843,6 @@ int ALSAStreamOps::format() const int pcmFormatBitWidth; int audioSystemFormat; -// if (!mHandle) -// return -1; - if (snd_pcm_hw_params_get_format(mHardwareParams, &ALSAFormat) < 0) { return -1; } @@ -868,8 +918,6 @@ status_t ALSAStreamOps::channelCount(int channelCount) { if (!mHandle) return NO_INIT; - // if(channelCount == 1) channelCount = 2; //Kamat: This is a fix added to avoid audioflinger crash (current audio driver does not support mono). Please check and modify suitably later. - err = snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, channelCount); if (err < 0) { LOGE("Unable to set channel count to %i: %s", @@ -930,6 +978,7 @@ void ALSAStreamOps::close() mHandle = NULL; if (handle) { + LOGV("ALSAStreamOps::close()"); snd_pcm_drain(handle); snd_pcm_close(handle); } @@ -1301,7 +1350,6 @@ AudioStreamOutALSA::AudioStreamOutALSA(AudioHardwareALSA *parent) : AudioStreamOutALSA::~AudioStreamOutALSA() { standby(); - mParent->mOutput = NULL; } @@ -1339,12 +1387,6 @@ status_t AudioStreamOutALSA::setParameters(const String8& keyValuePairs) param.remove(String8(AudioParameter::keyRouting)); } - else if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) - { - mParent->mOutput->mDefaults->sampleRate = value; - mParent->doRouting(mDevice); - param.remove(String8(AudioParameter::keySamplingRate)); - } if (param.size()) { status = BAD_VALUE; @@ -1382,6 +1424,7 @@ ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) size_t sent = 0; status_t err; + mParent->lock().lock(); AutoMutex lock(mLock); if (!mPowerLock) { @@ -1390,6 +1433,7 @@ ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; } + mParent->lock().unlock(); do { // write correct number of bytes per attempt @@ -1422,24 +1466,29 @@ status_t AudioStreamOutALSA::dump(int fd, const Vector<String16>& args) return NO_ERROR; } -status_t AudioStreamOutALSA::setDevice(int mode, uint32_t newDevice, uint32_t audio_mode) +status_t AudioStreamOutALSA::setDevice(int mode, + uint32_t newDevice, + uint32_t audio_mode, + bool force) { AutoMutex lock(mLock); LOGV("AudioStreamOutALSA::setDevice(mode %d, newDevice %x, audio_mode %d), mDevice %x", mode, newDevice, audio_mode, mDevice); - if (newDevice != mDevice) { - mParent->mRoutes[mParent->mMode] = newDevice; + if (newDevice != mDevice || force) { return ALSAStreamOps::setDevice(mode, newDevice, audio_mode); } return NO_ERROR; } status_t AudioStreamOutALSA::standby() { + AutoMutex _l(mParent->lock()); AutoMutex lock(mLock); LOGD("Inside AudioStreamOutALSA::standby\n"); - ALSAStreamOps::close(); + if (mParent->mode() != AudioSystem::MODE_IN_CALL) { + ALSAStreamOps::close(); + } if (mPowerLock) { release_wake_lock("AudioOutLock"); @@ -1481,7 +1530,6 @@ AudioStreamInALSA::AudioStreamInALSA(AudioHardwareALSA *parent) : AudioStreamInALSA::~AudioStreamInALSA() { standby(); - mParent->mInput = NULL; } status_t AudioStreamInALSA::setGain(float gain) @@ -1497,17 +1545,19 @@ ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes) snd_pcm_sframes_t n; status_t err; + mParent->lock().lock(); AutoMutex lock(mLock); - if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock"); // setMicStatus(1); LOGD("Calling setDevice from read@..%d.\n",__LINE__); - ALSAStreamOps::setDevice(mParent->mode(), mDevice,CAPTURE); + ALSAStreamOps::setDevice(mParent->mode(), mDevice, CAPTURE); mPowerLock = true; } + mParent->lock().unlock(); + if (!mHandle) { return -1; } @@ -1560,7 +1610,10 @@ status_t AudioStreamInALSA::dump(int fd, const Vector<String16>& args) return NO_ERROR; } -status_t AudioStreamInALSA::setDevice(int mode, uint32_t newDevice, uint32_t audio_mode) +status_t AudioStreamInALSA::setDevice(int mode, + uint32_t newDevice, + uint32_t audio_mode, + bool force) { AutoMutex lock(mLock); @@ -1569,7 +1622,9 @@ status_t AudioStreamInALSA::setDevice(int mode, uint32_t newDevice, uint32_t aud status_t AudioStreamInALSA::standby() { + AutoMutex _l(mParent->lock()); AutoMutex lock(mLock); + LOGD("Entering AudioStreamInALSA::standby\n"); ALSAStreamOps::close(); @@ -1586,14 +1641,21 @@ status_t AudioStreamInALSA::standby() status_t AudioStreamInALSA::setParameters(const String8& keyValuePairs) { AudioParameter param = AudioParameter(keyValuePairs); - String8 key = String8(AudioParameter::keyRouting); + String8 key = String8("vr_mode"); status_t status = NO_ERROR; - int device; + int value; LOGD("AudioStreamInALSA::setParameters() %s", keyValuePairs.string()); - if (param.getInt(key, device) == NO_ERROR) { - if(mHandle != NULL && device != 0) - setDevice(mParent->mode(), device, CAPTURE); + + if (param.getInt(key, value) == NO_ERROR) { + mParent->setVoiceRecordGain((value != 0)); + param.remove(key); + } + + key = String8(AudioParameter::keyRouting); + if (param.getInt(key, value) == NO_ERROR) { + if(mHandle != NULL && value != 0) + setDevice(mParent->mode(), value, CAPTURE); param.remove(key); } |