diff options
-rw-r--r-- | libaudio2/AudioHardware.cpp | 493 | ||||
-rw-r--r-- | libaudio2/AudioHardware.h | 27 |
2 files changed, 262 insertions, 258 deletions
diff --git a/libaudio2/AudioHardware.cpp b/libaudio2/AudioHardware.cpp index 6773109..89fc3f3 100644 --- a/libaudio2/AudioHardware.cpp +++ b/libaudio2/AudioHardware.cpp @@ -51,7 +51,6 @@ const uint32_t AudioHardware::inputSamplingRates[] = { AudioHardware::AudioHardware() : mInit(false), mMicMute(false), - mOutput(NULL), mPcm(NULL), mMixer(NULL), mPcmOpenCnt(0), @@ -70,10 +69,10 @@ AudioHardware::AudioHardware() : AudioHardware::~AudioHardware() { for (size_t index = 0; index < mInputs.size(); index++) { - closeInputStream((AudioStreamIn*)mInputs[index]); + closeInputStream(mInputs[index].get()); } mInputs.clear(); - closeOutputStream((AudioStreamOut*)mOutput); + closeOutputStream((AudioStreamOut*)mOutput.get()); if (mMixer) { mixer_close(mMixer); @@ -171,14 +170,14 @@ AudioStreamOut* AudioHardware::openOutputStream( uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) { - AudioStreamOutALSA* out = NULL; + sp <AudioStreamOutALSA> out; status_t rc; { // scope for the lock Mutex::Autolock lock(mLock); // only one output stream allowed - if (mOutput) { + if (mOutput != 0) { if (status) { *status = INVALID_OPERATION; } @@ -194,28 +193,29 @@ AudioStreamOut* AudioHardware::openOutputStream( } if (rc != NO_ERROR) { - if (out) { - delete out; + if (out != 0) { + out.clear(); } - out = NULL; } if (status) { *status = rc; } - return out; + return out.get(); } void AudioHardware::closeOutputStream(AudioStreamOut* out) { + sp <AudioStreamOutALSA> spOut; { Mutex::Autolock lock(mLock); - if (mOutput == 0 || mOutput != out) { + if (mOutput == 0 || mOutput.get() != out) { LOGW("Attempt to close invalid output stream"); return; } - mOutput = 0; + spOut = mOutput; + mOutput.clear(); } - delete out; + spOut.clear(); } AudioStreamIn* AudioHardware::openInputStream( @@ -232,7 +232,7 @@ AudioStreamIn* AudioHardware::openInputStream( } status_t rc = NO_ERROR; - AudioStreamInALSA* in = NULL;; + sp <AudioStreamInALSA> in; { // scope for the lock Mutex::Autolock lock(mLock); @@ -245,20 +245,21 @@ AudioStreamIn* AudioHardware::openInputStream( } if (rc != NO_ERROR) { - if (in) { - delete in; + if (in != 0) { + in.clear(); } - in = NULL; } if (status) { *status = rc; } - LOGV("AudioHardware::openInputStream()%p", in); - return in; + LOGV("AudioHardware::openInputStream()%p", in.get()); + return in.get(); } void AudioHardware::closeInputStream(AudioStreamIn* in) { + + sp<AudioStreamInALSA> spIn; { Mutex::Autolock lock(mLock); @@ -267,76 +268,93 @@ void AudioHardware::closeInputStream(AudioStreamIn* in) { LOGW("Attempt to close invalid input stream"); return; } + spIn = mInputs[index]; mInputs.removeAt(index); } LOGV("AudioHardware::closeInputStream()%p", in); - delete in; + spIn.clear(); } status_t AudioHardware::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_NORMAL) - { - if ((!mActivatedCP) && (mSecRilLibHandle) && (connectRILDIfRequired() == OK)) { - setCallClockSync(mRilClient, SOUND_CLOCK_START); - mActivatedCP = true; + sp<AudioStreamOutALSA> spOut; + sp<AudioStreamInALSA> spIn; + status_t status; + { // scope for the lock + AutoMutex lock(mLock); + int prevMode = mMode; + 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_NORMAL) + { + if ((!mActivatedCP) && (mSecRilLibHandle) && (connectRILDIfRequired() == OK)) { + setCallClockSync(mRilClient, SOUND_CLOCK_START); + mActivatedCP = true; + } } - } - if (mMode == AudioSystem::MODE_IN_CALL && !mInCallAudioMode) { - LOGV("setMode() openPcmOut_l()"); - openPcmOut_l(); - openMixer_l(); - setVoiceRecognition_l(false); - setIncallPath_l(mOutput->device()); - mInCallAudioMode = true; - } - if (mMode == AudioSystem::MODE_NORMAL && mInCallAudioMode) { - setVoiceRecognition_l(mVrModeEnabled); - LOGV("setMode() closePcmOut_l()"); - closeMixer_l(); - mOutput->setNextRoute(getOutputRouteFromDevice(mOutput->device())); - LOGV("setMode() closePcmOut_l()"); - closePcmOut_l(); - AudioStreamInALSA *input = getActiveInput_l(); - if (input != NULL) { - input->setNextRoute(getInputRouteFromDevice(input->device())); + if (mMode == AudioSystem::MODE_IN_CALL && !mInCallAudioMode) { + LOGV("setMode() openPcmOut_l()"); + openPcmOut_l(); + openMixer_l(); + setVoiceRecognition_l(false); + if (mOutput != 0) { + setIncallPath_l(mOutput->device()); + } + mInCallAudioMode = true; + } + if (mMode == AudioSystem::MODE_NORMAL && mInCallAudioMode) { + setVoiceRecognition_l(mVrModeEnabled); + LOGV("setMode() closePcmOut_l()"); + closeMixer_l(); + LOGV("setMode() closePcmOut_l()"); + closePcmOut_l(); + spOut = mOutput; + spIn = getActiveInput_l(); + mInCallAudioMode = false; } - mInCallAudioMode = false; - } - if (mMode == AudioSystem::MODE_NORMAL) { - if(mActivatedCP) - mActivatedCP = false; + if (mMode == AudioSystem::MODE_NORMAL) { + if(mActivatedCP) + mActivatedCP = false; + } } } + if (spOut != 0) { + spOut->setNextRoute(getOutputRouteFromDevice(spOut->device())); + } + if (spIn != 0) { + spIn->setNextRoute(getInputRouteFromDevice(spIn->device())); + } + return status; } status_t AudioHardware::setMicMute(bool state) { LOGV("setMicMute(%d) mMicMute %d", state, mMicMute); - AutoMutex lock(mLock); - if (mMicMute != state) { - mMicMute = state; - if (mMode != AudioSystem::MODE_IN_CALL) { - AudioStreamInALSA *input = getActiveInput_l(); - if (input != NULL) { - input->setNextRoute(getInputRouteFromDevice(input->device())); + sp<AudioStreamInALSA> spIn; + { + AutoMutex lock(mLock); + if (mMicMute != state) { + mMicMute = state; + // in call mute is handled by RIL + if (mMode != AudioSystem::MODE_IN_CALL) { + spIn = getActiveInput_l(); } } } + if (spIn != 0) { + spIn->setNextRoute(getInputRouteFromDevice(spIn->device())); + } + return NO_ERROR; } @@ -407,7 +425,7 @@ status_t AudioHardware::setVoiceVolume(float volume) (connectRILDIfRequired() == OK) ) { uint32_t device = AudioSystem::DEVICE_OUT_EARPIECE; - if (mOutput != NULL) { + if (mOutput != 0) { device = mOutput->device(); } int int_volume = (int)(volume * 5); @@ -463,14 +481,9 @@ status_t AudioHardware::dump(int fd, const Vector<String16>& args) return NO_ERROR; } -status_t AudioHardware::setIncallPath(uint32_t device) { - Mutex::Autolock lock(mLock); - return AudioHardware::setIncallPath_l(device); -} - status_t AudioHardware::setIncallPath_l(uint32_t device) { - LOGV("setIncallPath: device %x", device); + LOGV("setIncallPath_l: device %x", device); // Setup sound path for CP clocking if ((mSecRilLibHandle) && @@ -528,12 +541,6 @@ status_t AudioHardware::setIncallPath_l(uint32_t device) return NO_ERROR; } -struct pcm *AudioHardware::openPcmOut() -{ - AutoMutex lock(mLock); - return openPcmOut_l(); -} - struct pcm *AudioHardware::openPcmOut_l() { LOGI("openPcmOut_l() mPcmOpenCnt: %d", mPcmOpenCnt); @@ -558,12 +565,6 @@ struct pcm *AudioHardware::openPcmOut_l() return mPcm; } -void AudioHardware::closePcmOut() -{ - AutoMutex lock(mLock); - closePcmOut_l(); -} - void AudioHardware::closePcmOut_l() { LOGI("closePcmOut_l() mPcmOpenCnt: %d", mPcmOpenCnt); @@ -578,12 +579,6 @@ void AudioHardware::closePcmOut_l() } } -struct mixer *AudioHardware::openMixer() -{ - AutoMutex lock(mLock); - return openMixer_l(); -} - struct mixer *AudioHardware::openMixer_l() { LOGV("openMixer_l() mMixerOpenCnt: %d", mMixerOpenCnt); @@ -599,12 +594,6 @@ struct mixer *AudioHardware::openMixer_l() return mMixer; } -void AudioHardware::closeMixer() -{ - AutoMutex lock(mLock); - closeMixer_l(); -} - void AudioHardware::closeMixer_l() { LOGV("closeMixer_l() mMixerOpenCnt: %d", mMixerOpenCnt); @@ -628,9 +617,8 @@ const char *AudioHardware::getOutputRouteFromDevice(uint32_t device) if (mMode == AudioSystem::MODE_RINGTONE) return "RING_SPK"; else return "SPK"; case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE: -//uncomment when kernel change is submitted -// if (mMode == AudioSystem::MODE_RINGTONE) return "RING_HP_NO_MIC"; -// else return "HP_NO_MIC"; + if (mMode == AudioSystem::MODE_RINGTONE) return "RING_NO_MIC"; + else return "HP_NO_MIC"; case AudioSystem::DEVICE_OUT_WIRED_HEADSET: if (mMode == AudioSystem::MODE_RINGTONE) return "RING_HP"; else return "HP"; @@ -655,7 +643,7 @@ const char *AudioHardware::getVoiceRouteFromDevice(uint32_t device) case AudioSystem::DEVICE_OUT_SPEAKER: return "SPK"; case AudioSystem::DEVICE_OUT_WIRED_HEADPHONE: -// return "HP_NO_MIC"; + return "HP_NO_MIC"; case AudioSystem::DEVICE_OUT_WIRED_HEADSET: return "HP"; case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO: @@ -700,24 +688,20 @@ uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) } // getActiveInput_l() must be called with mLock held -AudioHardware::AudioStreamInALSA *AudioHardware::getActiveInput_l() +sp <AudioHardware::AudioStreamInALSA> AudioHardware::getActiveInput_l() { + sp< AudioHardware::AudioStreamInALSA> spIn; + for (size_t i = 0; i < mInputs.size(); i++) { // return first input found not being in standby mode // as only one input can be in this state if (!mInputs[i]->checkStandby()) { - return mInputs[i]; + spIn = mInputs[i]; + break; } } - return NULL; -} - - -status_t AudioHardware::setVoiceRecognition(bool enable) -{ - AutoMutex lock(mLock); - return setVoiceRecognition_l(enable); + return spIn; } status_t AudioHardware::setVoiceRecognition_l(bool enable) @@ -725,7 +709,6 @@ status_t AudioHardware::setVoiceRecognition_l(bool enable) LOGV("setVoiceRecognition_l(%d)", enable); if (enable != mVrModeEnabled) { if (!(enable && (mMode == AudioSystem::MODE_IN_CALL))) { - openMixer_l(); if (mMixer) { struct mixer_ctl *ctl= mixer_get_control(mMixer, "Recognition Control", 0); if (ctl == NULL) { @@ -736,7 +719,6 @@ status_t AudioHardware::setVoiceRecognition_l(bool enable) LOGV("mixer_ctl_select, Recognition Control, (%s)", mode); mixer_ctl_select(ctl, mode); } - closeMixer_l(); } mVrModeEnabled = enable; } @@ -805,47 +787,51 @@ ssize_t AudioHardware::AudioStreamOutALSA::write(const void* buffer, size_t byte const uint8_t* p = static_cast<const uint8_t*>(buffer); int ret; - AutoMutex lock(mLock); - if (mStandby) { - LOGV("open pcm_out driver"); + if (mHardware == NULL) return NO_INIT; - mPcm = mHardware->openPcmOut(); - if (!pcm_ready(mPcm)) { - LOGE("cannot open pcm_out driver: %s\n", pcm_error(mPcm)); - mHardware->closePcmOut(); - mPcm = 0; - goto Error; - } + { // scope for the lock + AutoMutex lock(mLock); - mMixer = mixer_open(); - if (mMixer) { - LOGV("open playback normal"); - mRouteCtl = mixer_get_control(mMixer, "Playback Path", 0); - } - if (mHardware->mode() == AudioSystem::MODE_IN_CALL) { + if (mStandby) { + AutoMutex hwLock(mHardware->lock()); + + LOGV("open pcm_out driver"); + mPcm = mHardware->openPcmOut_l(); + if (mPcm == NULL) { + LOGE("cannot open pcm_out driver: %s\n", pcm_error(mPcm)); + goto Error; + } + + mMixer = mHardware->openMixer_l(); + if (mMixer) { + LOGV("open playback normal"); + mRouteCtl = mixer_get_control(mMixer, "Playback Path", 0); + } + if (mHardware->mode() != AudioSystem::MODE_IN_CALL) { + next_route = mHardware->getOutputRouteFromDevice(mDevices); + LOGV("write() wakeup setting route %s", next_route); + mixer_ctl_select(mRouteCtl, next_route); + } next_route = 0; - } else { - next_route = mHardware->getOutputRouteFromDevice(mDevices); + acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); + mStandby = false; } - acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); - mStandby = false; - } - ret = pcm_write(mPcm,(void*) p, bytes); + ret = pcm_write(mPcm,(void*) p, bytes); - // FIXME:: this is done here as setting the route doesn't seem to work before reading - // first buffer - if (ret == 0) { - if (next_route && mRouteCtl) { - mixer_ctl_select(mRouteCtl, next_route); - next_route = 0; + if (ret == 0) { + if (next_route && mRouteCtl) { + LOGV("write() setting route %s", next_route); + mixer_ctl_select(mRouteCtl, next_route); + next_route = 0; + } + return bytes; } - return bytes; + LOGW("write error: %d", errno); + status = -errno; } - LOGW("write error: %d", errno); - status = -errno; - Error: + standby(); // Simulate audio output timing in case of error @@ -856,28 +842,34 @@ Error: status_t AudioHardware::AudioStreamOutALSA::standby() { + if (mHardware == NULL) return NO_INIT; + AutoMutex lock(mLock); - if (!mStandby) { - if (next_route && mRouteCtl) { - mixer_ctl_select(mRouteCtl, next_route); - next_route = 0; + + { // scope for the AudioHardware lock + AutoMutex hwLock(mHardware->lock()); + + if (!mStandby) { + if (next_route && mRouteCtl) { + mixer_ctl_select(mRouteCtl, next_route); + next_route = 0; + } + release_wake_lock("AudioOutLock"); + mStandby = true; + LOGV("AudioHardware pcm playback is going to standby."); } - release_wake_lock("AudioOutLock"); - mStandby = true; - LOGV("AudioHardware pcm playback is going to standby."); - } - if (mMixer) { - mixer_close(mMixer); - mMixer = 0; - if (mRouteCtl) { + if (mMixer) { + mHardware->closeMixer_l(); + mMixer = 0; mRouteCtl = 0; } + if (mPcm) { + mHardware->closePcmOut_l(); + mPcm = 0; + } } - if (mPcm) { - mHardware->closePcmOut(); - mPcm = 0; - } + return NO_ERROR; } @@ -900,8 +892,12 @@ status_t AudioHardware::AudioStreamOutALSA::setParameters(const String8& keyValu if (mHardware == NULL) return NO_INIT; + AutoMutex lock(mLock); + if (param.getInt(String8(AudioParameter::keyRouting), device) == NO_ERROR) { + AutoMutex hwLock(mHardware->lock()); + if (mDevices != (uint32_t)device) { mDevices = (uint32_t)device; if (mHardware->mode() != AudioSystem::MODE_IN_CALL) { @@ -909,9 +905,8 @@ status_t AudioHardware::AudioStreamOutALSA::setParameters(const String8& keyValu } } if (mHardware->mode() == AudioSystem::MODE_IN_CALL) { - mHardware->setIncallPath(device); + mHardware->setIncallPath_l(device); } - param.remove(String8(AudioParameter::keyRouting)); } @@ -919,6 +914,7 @@ status_t AudioHardware::AudioStreamOutALSA::setParameters(const String8& keyValu status = BAD_VALUE; } + return status; } @@ -944,7 +940,7 @@ status_t AudioHardware::AudioStreamOutALSA::getRenderPosition(uint32_t *dspFrame } //------------------------------------------------------------------------------ -// AudioStreamOutALSA +// AudioStreamInALSA //------------------------------------------------------------------------------ AudioHardware::AudioStreamInALSA::AudioStreamInALSA() : @@ -1021,77 +1017,84 @@ ssize_t AudioHardware::AudioStreamInALSA::read(void* buffer, ssize_t bytes) status_t status = NO_INIT; int ret; - AutoMutex lock(mLock); + if (mHardware == NULL) return NO_INIT; - if (mStandby) { - LOGV("open pcm_in driver"); + { // scope for the lock + AutoMutex lock(mLock); - unsigned flags = PCM_IN; - if (mChannels == AudioSystem::CHANNEL_IN_MONO) { - flags |= PCM_MONO; - } - flags |= (AUDIO_HW_IN_PERIOD_MULT - 1) << PCM_PERIOD_SZ_SHIFT; - flags |= (AUDIO_HW_IN_PERIOD_CNT - PCM_PERIOD_CNT_MIN) << PCM_PERIOD_CNT_SHIFT; + if (mStandby) { + unsigned flags = PCM_IN; + if (mChannels == AudioSystem::CHANNEL_IN_MONO) { + flags |= PCM_MONO; + } + flags |= (AUDIO_HW_IN_PERIOD_MULT - 1) << PCM_PERIOD_SZ_SHIFT; + flags |= (AUDIO_HW_IN_PERIOD_CNT - PCM_PERIOD_CNT_MIN) + << PCM_PERIOD_CNT_SHIFT; + + LOGV("open pcm_in driver"); + mPcm = pcm_open(flags); + if (!pcm_ready(mPcm)) { + LOGE("cannot open pcm_out driver: %s\n", pcm_error(mPcm)); + pcm_close(mPcm); + mPcm = 0; + goto Error; + } - mPcm = pcm_open(flags); - if (!pcm_ready(mPcm)) { - LOGE("cannot open pcm_out driver: %s\n", pcm_error(mPcm)); - pcm_close(mPcm); - mPcm = 0; - goto Error; - } + if (mDownSampler != NULL) { + mInPcmInBuf = 0; + mDownSampler->reset(); + } - mMixer = mixer_open(); - if (mMixer) { - mRouteCtl = mixer_get_control(mMixer, "Capture MIC Path", 0); - mMicCtl = mixer_get_control(mMixer, "Mic Status", 0); - if (mMicCtl) { - LOGV("turn mic ON"); - mixer_ctl_select(mRouteCtl, "MIC_USE"); + AutoMutex hwLock(mHardware->lock()); + + mMixer = mHardware->openMixer_l(); + if (mMixer) { + mRouteCtl = mixer_get_control(mMixer, "Capture MIC Path", 0); } - } - if (mDownSampler != NULL) { - mInPcmInBuf = 0; - mDownSampler->reset(); - } - if (mHardware->mode() != AudioSystem::MODE_IN_CALL) { - next_route = mHardware->getInputRouteFromDevice(mDevices); + if (mHardware->mode() != AudioSystem::MODE_IN_CALL) { + next_route = mHardware->getInputRouteFromDevice(mDevices); + LOGV("read() wakeup setting route %s", next_route); + mixer_ctl_select(mRouteCtl, next_route); + } + next_route = 0; + + acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock"); + mStandby = false; } - acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock"); - mStandby = false; - } - if (mDownSampler != NULL) { - size_t frames = bytes / frameSize(); - size_t framesIn = 0; - mReadStatus = 0; - do { - size_t outframes = frames - framesIn; - mDownSampler->resample((int16_t *)buffer + (framesIn * mChannelCount), &outframes); - framesIn += outframes; - } while ((framesIn < frames) && mReadStatus == 0); - ret = mReadStatus; - bytes = framesIn * frameSize(); - } else { - ret = pcm_read(mPcm, buffer, bytes); - } - // FIXME:: this is done here as setting the route doesn't seem to work before reading - // first buffer - if (ret == 0) { - if (next_route && mRouteCtl) { - LOGV("set route : %s ", next_route); - mixer_ctl_select(mRouteCtl, next_route); - next_route = 0; + if (mDownSampler != NULL) { + size_t frames = bytes / frameSize(); + size_t framesIn = 0; + mReadStatus = 0; + do { + size_t outframes = frames - framesIn; + mDownSampler->resample( + (int16_t *)buffer + (framesIn * mChannelCount), + &outframes); + framesIn += outframes; + } while ((framesIn < frames) && mReadStatus == 0); + ret = mReadStatus; + bytes = framesIn * frameSize(); + } else { + ret = pcm_read(mPcm, buffer, bytes); } - return bytes; - } - LOGW("read error: %d", ret); - status = ret; + if (ret == 0) { + if (next_route && mRouteCtl) { + LOGV("read() setting route %s", next_route); + mixer_ctl_select(mRouteCtl, next_route); + next_route = 0; + } + return bytes; + } + LOGW("read error: %d", ret); + status = ret; + } Error: + standby(); // Simulate audio output timing in case of error @@ -1102,34 +1105,33 @@ Error: status_t AudioHardware::AudioStreamInALSA::standby() { + if (mHardware == NULL) return NO_INIT; + AutoMutex lock(mLock); - if (!mStandby) { - if (next_route && mRouteCtl) { - mixer_ctl_select(mRouteCtl, next_route); - next_route = 0; - } - release_wake_lock("AudioInLock"); - mStandby = true; - LOGI("AudioHardware pcm playback is going to standby."); - } + { // scope for AudioHardware lock + AutoMutex hwLock(mHardware->lock()); - if (mPcm) { - pcm_close(mPcm); - mPcm = 0; - } - if (mMixer) { - if (mMicCtl) { - LOGV("turn mic OFF"); - mixer_ctl_select(mMicCtl, "MIC_NO_USE"); - mMicCtl = 0; + if (!mStandby) { + if (next_route && mRouteCtl) { + mixer_ctl_select(mRouteCtl, next_route); + next_route = 0; + } + release_wake_lock("AudioInLock"); + mStandby = true; + LOGI("AudioHardware pcm playback is going to standby."); } - mixer_close(mMixer); - mMixer = 0; - if (mRouteCtl) { + + if (mMixer) { + mHardware->closeMixer_l(); + mMixer = 0; mRouteCtl = 0; } + if (mPcm) { + pcm_close(mPcm); + mPcm = 0; + } } return NO_ERROR; } @@ -1153,14 +1155,23 @@ status_t AudioHardware::AudioStreamInALSA::setParameters(const String8& keyValue if (mHardware == NULL) return NO_INIT; + AutoMutex lock(mLock); + if (param.getInt(String8(VOICE_REC_MODE_KEY), value) == NO_ERROR) { - mHardware->setVoiceRecognition((value != 0)); + AutoMutex hwLock(mHardware->lock()); + + mHardware->openMixer_l(); + mHardware->setVoiceRecognition_l((value != 0)); + mHardware->closeMixer_l(); + param.remove(String8(VOICE_REC_MODE_KEY)); } if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { if (value != 0) { + AutoMutex hwLock(mHardware->lock()); + if (mDevices != (uint32_t)value) { if (mHardware->mode() != AudioSystem::MODE_IN_CALL) { next_route = mHardware->getInputRouteFromDevice((uint32_t)value); diff --git a/libaudio2/AudioHardware.h b/libaudio2/AudioHardware.h index 4fdb437..2049cd5 100644 --- a/libaudio2/AudioHardware.h +++ b/libaudio2/AudioHardware.h @@ -109,26 +109,19 @@ public: const char *getInputRouteFromDevice(uint32_t device); const char *getVoiceRouteFromDevice(uint32_t device); - status_t setIncallPath(uint32_t device); status_t setIncallPath_l(uint32_t device); - status_t setVoiceRecognition(bool enable); status_t setVoiceRecognition_l(bool enable); static uint32_t getInputSampleRate(uint32_t sampleRate); - AudioStreamInALSA* getActiveInput_l(); + sp <AudioStreamInALSA> getActiveInput_l(); - void lock() { mLock.lock(); } - void unlock() { mLock.unlock(); } + Mutex& lock() { return mLock; } - struct pcm *openPcmOut(); struct pcm *openPcmOut_l(); - void closePcmOut(); void closePcmOut_l(); - struct mixer *openMixer(); struct mixer *openMixer_l(); - void closeMixer(); void closeMixer_l(); protected: @@ -138,8 +131,8 @@ private: bool mInit; bool mMicMute; - AudioStreamOutALSA* mOutput; - SortedVector <AudioStreamInALSA*> mInputs; + sp <AudioStreamOutALSA> mOutput; + SortedVector < sp<AudioStreamInALSA> > mInputs; Mutex mLock; struct pcm* mPcm; struct mixer* mMixer; @@ -166,7 +159,7 @@ private: static uint32_t checkInputSampleRate(uint32_t sampleRate); static const uint32_t inputSamplingRates[]; - class AudioStreamOutALSA : public AudioStreamOut + class AudioStreamOutALSA : public AudioStreamOut, public RefBase { public: AudioStreamOutALSA(); @@ -192,14 +185,15 @@ private: { return INVALID_OPERATION; } virtual ssize_t write(const void* buffer, size_t bytes); virtual status_t standby(); + bool checkStandby(); + virtual status_t dump(int fd, const Vector<String16>& args); - bool checkStandby(); virtual status_t setParameters(const String8& keyValuePairs); virtual String8 getParameters(const String8& keys); uint32_t device() { return mDevices; } virtual status_t getRenderPosition(uint32_t *dspFrames); - void setNextRoute(const char *route) { next_route = route; } + void setNextRoute(const char *route) { AutoMutex lock(mLock); next_route = route; } private: @@ -274,7 +268,7 @@ private: }; - class AudioStreamInALSA : public AudioStreamIn, public BufferProvider + class AudioStreamInALSA : public AudioStreamIn, public BufferProvider, public RefBase { public: @@ -299,7 +293,7 @@ private: virtual String8 getParameters(const String8& keys); virtual unsigned int getInputFramesLost() const { return 0; } uint32_t device() { return mDevices; } - void setNextRoute(const char *route) { next_route = route; } + void setNextRoute(const char *route) { AutoMutex lock(mLock); next_route = route; } static size_t getBufferSize(uint32_t sampleRate, int channelCount); @@ -313,7 +307,6 @@ private: struct pcm *mPcm; struct mixer *mMixer; struct mixer_ctl *mRouteCtl; - struct mixer_ctl *mMicCtl; const char *next_route; int mStartCount; int mRetryCount; |