diff options
Diffstat (limited to 'libaudio')
-rwxr-xr-x | libaudio/AudioHardwareALSA.cpp | 258 | ||||
-rwxr-xr-x | libaudio/AudioHardwareALSA.h | 38 |
2 files changed, 183 insertions, 113 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); } diff --git a/libaudio/AudioHardwareALSA.h b/libaudio/AudioHardwareALSA.h index f65aa68..22821ab 100755 --- a/libaudio/AudioHardwareALSA.h +++ b/libaudio/AudioHardwareALSA.h @@ -89,6 +89,10 @@ namespace android class ALSAStreamOps { + public: + uint32_t device() { return mDevice; } + void close(); + protected: friend class AudioStreamOutALSA; friend class AudioStreamInALSA; @@ -124,13 +128,12 @@ namespace android uint32_t getAndroidChannels(int channelCount) const; status_t open(int mode, uint32_t device); - void close(); status_t setSoftwareParams(); status_t setPCMFormat(snd_pcm_format_t format); status_t setHardwareResample(bool resample); const char *streamName(); - virtual status_t setDevice(int mode, uint32_t device, uint32_t audio_mode); + status_t setDevice(int mode, uint32_t device, uint32_t audio_mode); const char *deviceName(int mode, uint32_t device); @@ -187,7 +190,8 @@ namespace android virtual ssize_t write(const void *buffer, size_t bytes); virtual status_t dump(int fd, const Vector<String16>& args); - virtual status_t setDevice(int mode, uint32_t newDevice, uint32_t audio_mode); + status_t setDevice(int mode, uint32_t newDevice, uint32_t audio_mode, + bool force = false); virtual status_t setVolume(float left, float right); //Tushar: New arch status_t setVolume(float volume); @@ -198,7 +202,7 @@ namespace android virtual String8 getParameters(const String8& keys); virtual status_t getRenderPosition(uint32_t *dspFrames); - + bool isActive() { return mPowerLock; } private: AudioHardwareALSA *mParent; @@ -238,7 +242,8 @@ namespace android virtual ssize_t read(void* buffer, ssize_t bytes); virtual status_t dump(int fd, const Vector<String16>& args); - virtual status_t setDevice(int mode, uint32_t newDevice, uint32_t audio_mode); + status_t setDevice(int mode, uint32_t newDevice, uint32_t audio_mode, + bool force = false); virtual status_t setGain(float gain); @@ -249,6 +254,8 @@ namespace android virtual unsigned int getInputFramesLost() const { return 0; } + bool isActive() { return mPowerLock; } + private: AudioHardwareALSA *mParent; bool mPowerLock; @@ -267,15 +274,11 @@ namespace android */ virtual status_t initCheck(); - /** - * put the audio hardware into standby mode to conserve power. Returns - * status based on include/utils/Errors.h - */ - virtual status_t standby(); - /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */ virtual status_t setVoiceVolume(float volume); + virtual status_t setMode(int mode); + /** * set the audio volume for all audio activities other than voice call. * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned, @@ -312,6 +315,10 @@ namespace android static const uint32_t inputSamplingRates[]; int mode() { return mMode; } + Mutex& lock() { return mLock; } + + int setVoiceRecordGain(bool enable); + int setVoiceRecordGain_l(bool enable); protected: /** @@ -320,7 +327,8 @@ namespace android * doRouting when required. If the device has any special requirements these * methods can be overriden. */ - virtual status_t doRouting(uint32_t device); + status_t doRouting(uint32_t device, bool force = false); + status_t doRouting_l(uint32_t device, bool force = false); virtual status_t dump(int fd, const Vector<String16>& args); @@ -331,13 +339,12 @@ namespace android AudioStreamOutALSA *mOutput; AudioStreamInALSA *mInput; - uint32_t mRoutes[AudioSystem::NUM_MODES]; private: Mutex mLock; - bool mActivatedInputDevice; - void *mSecRilLibHandle; HRilClient mRilClient; + bool mVrModeEnabled; + HRilClient (*openClientRILD) (void); int (*disconnectRILD) (HRilClient); int (*closeClientRILD) (HRilClient); @@ -348,6 +355,7 @@ namespace android void loadRILD(void); status_t connectRILDIfRequired(void); + }; }; // namespace android |