summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-11-18 17:27:21 -0800
committerEric Laurent <elaurent@google.com>2010-11-19 09:13:34 -0800
commite784e44a0402aa4e9489e0b9f2f3d3685cf76a93 (patch)
tree7d3c1f30658fe5d17e2b88f2d006f5bb55159bfb
parent7d308b99544a6e8c5387ccee7095a780dcd9f957 (diff)
downloadmsm7k-e784e44a0402aa4e9489e0b9f2f3d3685cf76a93.tar.gz
Fix issue 3158317.
Do not open the input device when opening the input stream but only when the input stream starts. This avoids blocking the thread executing openInputStream() on the pcm input driver mutex while this mutex is constantly acquired and released by the high priority audio input thread. It also allows an app to open an input stream while another thread is recording if it does not use it immediately (useful for voice search and VoIP). Also did some clean up in output and input stream standby logic. Change-Id: I69c82f5833f7a034d828001f87e02745d7683b65
-rw-r--r--libaudio-qsd8k/AudioHardware.cpp198
-rw-r--r--libaudio-qsd8k/AudioHardware.h10
2 files changed, 98 insertions, 110 deletions
diff --git a/libaudio-qsd8k/AudioHardware.cpp b/libaudio-qsd8k/AudioHardware.cpp
index 669889f..f6cfc9d 100644
--- a/libaudio-qsd8k/AudioHardware.cpp
+++ b/libaudio-qsd8k/AudioHardware.cpp
@@ -16,7 +16,7 @@
#include <math.h>
-#define LOG_NDEBUG 1
+//#define LOG_NDEBUG 0
#define LOG_TAG "AudioHardwareQSD"
#include <utils/Log.h>
#include <utils/String8.h>
@@ -625,7 +625,7 @@ status_t AudioHardware::setVoiceVolume(float v)
LOGD("HAC enable: Setting in-call volume to maximum.\n");
set_volume_rpc(VOICE_VOLUME_MAX);
} else {
- LOGI("voice volume %f (range is 0 to %d)", vol, VOICE_VOLUME_MAX);
+ LOGI("voice volume %d (range is 0 to %d)", vol, VOICE_VOLUME_MAX);
set_volume_rpc(vol); //always set current device
}
mVoiceVolume = vol;
@@ -1522,7 +1522,7 @@ AudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l()
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]->state() > AudioStreamInMSM72xx::AUDIO_INPUT_CLOSED) {
+ if (!mInputs[i]->checkStandby()) {
return mInputs[i];
}
}
@@ -1598,9 +1598,11 @@ ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t b
if (errCount++ < 10) {
LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno);
}
+ release_wake_lock(kOutputWakelockStr);
goto Error;
}
mFd = status;
+ mStandby = false;
// configuration
LOGV("get config");
@@ -1640,8 +1642,6 @@ ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t b
LOGE("Cannot start pcm playback");
goto Error;
}
-
- mStandby = false;
}
while (count) {
@@ -1650,7 +1650,10 @@ ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t b
count -= written;
p += written;
} else {
- if (errno != EAGAIN) return written;
+ if (errno != EAGAIN) {
+ status = written;
+ goto Error;
+ }
mRetryCount++;
LOGD("EAGAIN - retry");
}
@@ -1659,28 +1662,27 @@ ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t b
return bytes;
Error:
- if (mFd >= 0) {
- ::close(mFd);
- mFd = -1;
- }
+
+ standby();
+
// Simulate audio output timing in case of error
- usleep(bytes * 1000000 / frameSize() / sampleRate());
- release_wake_lock(kOutputWakelockStr);
+ usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate());
return status;
}
status_t AudioHardware::AudioStreamOutMSM72xx::standby()
{
- status_t status = NO_ERROR;
- if (!mStandby && mFd >= 0) {
- ::close(mFd);
- mFd = -1;
+ if (!mStandby) {
+ LOGD("AudioHardware pcm playback is going to standby.");
+ if (mFd >= 0) {
+ ::close(mFd);
+ mFd = -1;
+ }
LOGV("release output wakelock");
release_wake_lock(kOutputWakelockStr);
+ mStandby = true;
}
- mStandby = true;
- LOGD("AudioHardware pcm playback is going to standby.");
- return status;
+ return NO_ERROR;
}
status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
@@ -1711,6 +1713,7 @@ status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String1
return NO_ERROR;
}
+
bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
{
return mStandby;
@@ -1762,7 +1765,7 @@ status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFr
// ----------------------------------------------------------------------------
AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
- mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0),
+ mHardware(0), mFd(-1), mStandby(true), mRetryCount(0),
mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS),
mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFSZ),
mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0)
@@ -1800,72 +1803,14 @@ status_t AudioHardware::AudioStreamInMSM72xx::set(
return -EPERM;
}
- // open audio input device
- status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
- if (status < 0) {
- LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
- goto Error;
- }
- mFd = status;
mBufferSize = hw->getBufferSize(*pRate, AudioSystem::popCount(*pChannels));
-
- // configuration
- LOGV("get config");
- struct msm_audio_config config;
- status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
- if (status < 0) {
- LOGE("Cannot read config");
- goto Error;
- }
-
- LOGV("set config");
- config.channel_count = AudioSystem::popCount(*pChannels);
- config.sample_rate = *pRate;
- config.buffer_size = mBufferSize;
- config.buffer_count = 2;
- config.codec_type = CODEC_TYPE_PCM;
- status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
- if (status < 0) {
- LOGE("Cannot set config");
- if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) {
- if (config.channel_count == 1) {
- *pChannels = AudioSystem::CHANNEL_IN_MONO;
- } else {
- *pChannels = AudioSystem::CHANNEL_IN_STEREO;
- }
- *pRate = config.sample_rate;
- }
- goto Error;
- }
-
- LOGV("confirm config");
- status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
- if (status < 0) {
- LOGE("Cannot read config");
- goto Error;
- }
- LOGV("buffer_size: %u", config.buffer_size);
- LOGV("buffer_count: %u", config.buffer_count);
- LOGV("channel_count: %u", config.channel_count);
- LOGV("sample_rate: %u", config.sample_rate);
-
mDevices = devices;
mFormat = AUDIO_HW_IN_FORMAT;
mChannels = *pChannels;
- mSampleRate = config.sample_rate;
- mBufferSize = config.buffer_size;
-
- //mHardware->setMicMute_nosync(false);
- mState = AUDIO_INPUT_OPENED;
+ mSampleRate = *pRate;
return NO_ERROR;
-Error:
- if (mFd >= 0) {
- ::close(mFd);
- mFd = -1;
- }
- return status;
}
AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
@@ -1876,33 +1821,65 @@ AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
{
- LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
+// LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
if (!mHardware) return -1;
size_t count = bytes;
uint8_t* p = static_cast<uint8_t*>(buffer);
+ status_t status = NO_ERROR;
- if (mState < AUDIO_INPUT_OPENED) {
- Mutex::Autolock lock(mHardware->mLock);
- if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) {
- return -1;
+ if (mStandby) {
+ { // scope for the lock
+ Mutex::Autolock lock(mHardware->mLock);
+ LOGV("acquire input wakelock");
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, kInputWakelockStr);
+ // open audio input device
+ status = ::open("/dev/msm_pcm_in", O_RDWR);
+ if (status < 0) {
+ LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
+ LOGV("release input wakelock");
+ release_wake_lock(kInputWakelockStr);
+ goto Error;
+ }
+ mFd = status;
+ mStandby = false;
+
+ // configuration
+ LOGV("get config");
+ struct msm_audio_config config;
+ status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
+ if (status < 0) {
+ LOGE("Cannot read config");
+ goto Error;
+ }
+
+ LOGV("set config");
+ config.channel_count = AudioSystem::popCount(mChannels);
+ config.sample_rate = mSampleRate;
+ config.buffer_size = mBufferSize;
+ config.buffer_count = 2;
+ config.codec_type = CODEC_TYPE_PCM;
+ status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
+ if (status < 0) {
+ LOGE("Cannot set config");
+ goto Error;
+ }
+
+ LOGV("buffer_size: %u", config.buffer_size);
+ LOGV("buffer_count: %u", config.buffer_count);
+ LOGV("channel_count: %u", config.channel_count);
+ LOGV("sample_rate: %u", config.sample_rate);
}
- }
- if (mState < AUDIO_INPUT_STARTED) {
- mState = AUDIO_INPUT_STARTED;
mHardware->set_mRecordState(1);
// make sure a1026 config is re-applied even is input device is not changed
mHardware->clearCurDevice();
mHardware->doRouting();
- LOGV("acquire input wakelock");
- acquire_wake_lock(PARTIAL_WAKE_LOCK, kInputWakelockStr);
uint32_t acdb_id = mHardware->getACDB(MOD_REC, mHardware->get_snd_dev());
if (ioctl(mFd, AUDIO_START, &acdb_id)) {
LOGE("Error starting record");
- standby();
- return -1;
+ goto Error;
}
}
@@ -1912,37 +1889,54 @@ ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
count -= bytesRead;
p += bytesRead;
} else {
- if (errno != EAGAIN) return bytesRead;
+ if (errno != EAGAIN) {
+ status = bytesRead;
+ goto Error;
+ }
mRetryCount++;
LOGD("EAGAIN - retrying");
}
}
return bytes;
+
+Error:
+ standby();
+
+ // Simulate audio input timing in case of error
+ usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate());
+
+ return status;
}
status_t AudioHardware::AudioStreamInMSM72xx::standby()
{
- if (mState > AUDIO_INPUT_CLOSED) {
+ if (!mStandby) {
+ LOGD("AudioHardware PCM record is going to standby.");
if (mFd >= 0) {
::close(mFd);
mFd = -1;
}
- mState = AUDIO_INPUT_CLOSED;
LOGV("release input wakelock");
release_wake_lock(kInputWakelockStr);
- }
- if (!mHardware) return -1;
+ mStandby = true;
- mHardware->set_mRecordState(0);
- // make sure a1026 config is re-applied even is input device is not changed
- mHardware->clearCurDevice();
- mHardware->doRouting();
+ if (!mHardware) return -1;
+
+ mHardware->set_mRecordState(0);
+ // make sure a1026 config is re-applied even is input device is not changed
+ mHardware->clearCurDevice();
+ mHardware->doRouting();
+ }
- LOGD("AudioHardware PCM record is going to standby.");
return NO_ERROR;
}
+bool AudioHardware::AudioStreamInMSM72xx::checkStandby()
+{
+ return mStandby;
+}
+
status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -1961,7 +1955,7 @@ status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16
result.append(buffer);
snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
result.append(buffer);
- snprintf(buffer, SIZE, "\tmState: %d\n", mState);
+ snprintf(buffer, SIZE, "\tmStandby: %d\n", mStandby);
result.append(buffer);
snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
result.append(buffer);
diff --git a/libaudio-qsd8k/AudioHardware.h b/libaudio-qsd8k/AudioHardware.h
index 3be83ae..a911a97 100644
--- a/libaudio-qsd8k/AudioHardware.h
+++ b/libaudio-qsd8k/AudioHardware.h
@@ -274,12 +274,6 @@ private:
class AudioStreamInMSM72xx : public AudioStreamIn {
public:
- enum input_state {
- AUDIO_INPUT_CLOSED,
- AUDIO_INPUT_OPENED,
- AUDIO_INPUT_STARTED
- };
-
AudioStreamInMSM72xx();
virtual ~AudioStreamInMSM72xx();
status_t set(AudioHardware* mHardware,
@@ -300,12 +294,12 @@ private:
virtual String8 getParameters(const String8& keys);
virtual unsigned int getInputFramesLost() const { return 0; }
uint32_t devices() { return mDevices; }
- int state() const { return mState; }
+ bool checkStandby();
private:
AudioHardware* mHardware;
int mFd;
- int mState;
+ bool mStandby;
int mRetryCount;
int mFormat;
uint32_t mChannels;