summaryrefslogtreecommitdiffstats
path: root/libaudio
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-10-08 17:13:40 -0700
committerEric Laurent <elaurent@google.com>2010-10-08 17:23:10 -0700
commit675e710e22b2e7c7752c19e7501e6a60ec88aae7 (patch)
tree1836ce8b37d6899b164cc04e23995fb080193d98 /libaudio
parent8bcbed1192257cebf002678b1a45d443833f359f (diff)
downloaddevice_samsung_crespo-675e710e22b2e7c7752c19e7501e6a60ec88aae7.zip
device_samsung_crespo-675e710e22b2e7c7752c19e7501e6a60ec88aae7.tar.gz
device_samsung_crespo-675e710e22b2e7c7752c19e7501e6a60ec88aae7.tar.bz2
Fix several in call audio issues.
- 1: make sure that we restore normal mode in codec when the call is ended. - 2: make sure that we set in call mode in codec when the call is started even if output stream is playing. Merged support for special mic gain setting for voice recognition. Some more cleanup. Change-Id: I00ab773ec294f7b186b463177372ece5b520a386
Diffstat (limited to 'libaudio')
-rwxr-xr-xlibaudio/AudioHardwareALSA.cpp258
-rwxr-xr-xlibaudio/AudioHardwareALSA.h38
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