Skip to content
Permalink
Browse files

Audio: Update with latest CAF changes (jb_rel branch)

  • Loading branch information
Fagulhas committed Dec 20, 2012
1 parent b398349 commit 3b1cab179e67996d3fade9451a2d0e563673ad29
Showing with 202 additions and 119 deletions.
  1. +90 −56 audio/AudioHardware.cpp
  2. +6 −4 audio/AudioHardware.h
  3. +92 −57 audio/AudioHardware_cad.cpp
  4. +14 −2 audio/AudioPolicyManager.cpp
@@ -1746,18 +1746,22 @@ bool AudioHardware::isFMAnalog()
return isAfm;
}
#endif
status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input)
status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input, int outputDevice)
{
/* currently this code doesn't work without the htc libacoustic */

Mutex::Autolock lock(mLock);
uint32_t outputDevices = mOutput->devices();
uint32_t outputDevices;
status_t ret = NO_ERROR;
int new_snd_device = -1;
#ifdef QCOM_FM_ENABLED
bool enableDgtlFmDriver = false;
#endif

if (outputDevice)
outputDevices = outputDevice;
else
outputDevices = mOutput->devices();

//int (*msm72xx_enable_audpp)(int);
//msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp");
@@ -3327,6 +3331,8 @@ AudioHardware::AudioSessionOutLPA::AudioSessionOutLPA( AudioHardware *hw,
*status = BAD_VALUE;

mPaused = false;
mIsDriverStarted = false;
mGenerateEOS = true;
mSeeking = false;
mReachedEOS = false;
mSkipWrite = false;
@@ -3347,11 +3353,11 @@ AudioHardware::AudioSessionOutLPA::AudioSessionOutLPA( AudioHardware *hw,
return;
}

openAudioSessionDevice();
*status = openAudioSessionDevice();

//Creates the event thread to poll events from LPA Driver
createEventThread();
*status = NO_ERROR;
if (*status == NO_ERROR)
createEventThread();
}

AudioHardware::AudioSessionOutLPA::~AudioSessionOutLPA()
@@ -3377,7 +3383,7 @@ status_t AudioHardware::AudioSessionOutLPA::setParameters(const String8& keyValu
if (param.getInt(key, device) == NO_ERROR) {
mDevices = device;
ALOGV("set output routing %x", mDevices);
status = mHardware->doRouting(NULL);
status = mHardware->doRouting(NULL, device);
param.remove(key);
}

@@ -3407,10 +3413,21 @@ ssize_t AudioHardware::AudioSessionOutLPA::write(const void* buffer, size_t byte
int err;
ALOGV("write Empty Queue size() = %d, Filled Queue size() = %d ",
mEmptyQueue.size(),mFilledQueue.size());

if (mSkipWrite) {
mSkipWrite = false;
if (bytes < LPA_BUFFER_SIZE)
bytes = 0;
else
return 0;
}

if (mSkipWrite)
mSkipWrite = false;

//2.) Dequeue the buffer from empty buffer queue. Copy the data to be
// written into the buffer. Then Enqueue the buffer to the filled
// buffer queue
mEmptyQueueMutex.lock();
List<BuffersAllocated>::iterator it = mEmptyQueue.begin();
BuffersAllocated buf = *it;
mEmptyQueue.erase(it);
@@ -3434,29 +3451,39 @@ ssize_t AudioHardware::AudioSessionOutLPA::write(const void* buffer, size_t byte
}
if (timeStarted == 0)
timeStarted = nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_MONOTONIC));
} else {
/* Put the buffer back into requestQ */
ALOGV("mEmptyQueueMutex locking: %d", __LINE__);
mEmptyQueueMutex.lock();
ALOGV("mEmptyQueueMutex locked: %d", __LINE__);
mEmptyQueue.push_back(buf);
ALOGV("mEmptyQueueMutex unlocking: %d", __LINE__);
mEmptyQueueMutex.unlock();
ALOGV("mEmptyQueueMutex unlocked: %d", __LINE__);
//Post EOS in case the filled queue is empty and EOS is reached.
if (mFilledQueue.empty() && mReachedEOS) {
ALOGV("mEosEventReceived made true");
mEosEventReceived = true;
} else {
/* Put the buffer back into requestQ */
ALOGV("mEmptyQueueMutex locking: %d", __LINE__);
mEmptyQueueMutex.lock();
ALOGV("mEmptyQueueMutex locked: %d", __LINE__);
mEmptyQueue.push_back(buf);
ALOGV("mEmptyQueueMutex unlocking: %d", __LINE__);
mEmptyQueueMutex.unlock();
ALOGV("mEmptyQueueMutex unlocked: %d", __LINE__);
//Post EOS in case the filled queue is empty and EOS is reached.
mReachedEOS = true;
mFilledQueueMutex.lock();
if (mFilledQueue.empty() && !mEosEventReceived) {
ALOGV("mEosEventReceived made true");
mEosEventReceived = true;
if (mObserver != NULL) {
ALOGV("mObserver: posting EOS");
mObserver->postEOS(0);
}
}
mFilledQueueMutex.unlock();
return NO_ERROR;
}
mFilledQueueMutex.lock();
mFilledQueue.push_back(buf);
mFilledQueueMutex.unlock();

ALOGV("PCM write start");
//3.) Write the buffer to the Driver
if ( ioctl(afd, AUDIO_ASYNC_WRITE, &aio_buf_local ) < 0 ) {
ALOGE("error on async write\n");
if(mIsDriverStarted) {
if (ioctl(afd, AUDIO_ASYNC_WRITE, &aio_buf_local) < 0 ) {
ALOGE("error on async write\n");
}
}
ALOGV("PCM write complete");

@@ -3528,6 +3555,7 @@ status_t AudioHardware::AudioSessionOutLPA::openAudioSessionDevice( )
}

start();
bufferAlloc();

return status;
}
@@ -3538,7 +3566,7 @@ void AudioHardware::AudioSessionOutLPA::bufferAlloc( )
void *ion_buf; int32_t ion_fd;
struct msm_audio_ion_info ion_info;
//1. Open the ion_audio
ionfd = open("/dev/ion", O_RDONLY);
ionfd = open("/dev/ion", O_RDONLY | O_SYNC);
if (ionfd < 0) {
ALOGE("/dev/ion open failed \n");
return;
@@ -3566,8 +3594,7 @@ void* AudioHardware::AudioSessionOutLPA::memBufferAlloc(int nSize, int32_t *ion_

alloc_data.len = nSize;
alloc_data.align = 0x1000;
alloc_data.heap_mask = ION_HEAP(ION_AUDIO_HEAP_ID);
alloc_data.flags = 0;
alloc_data.flags = ION_HEAP(ION_AUDIO_HEAP_ID);
int rc = ioctl(ionfd, ION_IOC_ALLOC, &alloc_data);
if (rc) {
ALOGE("ION_IOC_ALLOC ioctl failed\n");
@@ -3627,6 +3654,7 @@ void AudioHardware::AudioSessionOutLPA::bufferDeAlloc()
// De-Allocate ION buffers
int rc = 0;
//Remove all the buffers from empty queue
mEmptyQueueMutex.lock();
while (!mEmptyQueue.empty()) {
List<BuffersAllocated>::iterator it = mEmptyQueue.begin();
BuffersAllocated &ionBuffer = *it;
@@ -3649,8 +3677,10 @@ void AudioHardware::AudioSessionOutLPA::bufferDeAlloc()
ALOGE("Removing from empty Q");
mEmptyQueue.erase(it);
}
mEmptyQueueMutex.unlock();

//Remove all the buffers from Filled queue
mFilledQueueMutex.lock();
while(!mFilledQueue.empty()){
List<BuffersAllocated>::iterator it = mFilledQueue.begin();
BuffersAllocated &ionBuffer = *it;
@@ -3673,6 +3703,7 @@ void AudioHardware::AudioSessionOutLPA::bufferDeAlloc()
ALOGV("Removing from Filled Q");
mFilledQueue.erase(it);
}
mFilledQueueMutex.unlock();
if (ionfd >= 0) {
close(ionfd);
ionfd = -1;
@@ -3722,7 +3753,7 @@ void AudioHardware::AudioSessionOutLPA::eventThreadEntry()
rc = ioctl(afd, AUDIO_GET_EVENT, &cur_pcmdec_event);
ALOGE("pcm dec Event Thread rc = %d and errno is %d",rc, errno);

if ( (rc < 0) && (errno == ENODEV ) ) {
if ( (rc < 0) && ((errno == ENODEV) || (errno == EBADF)) ) {
ALOGV("AUDIO__GET_EVENT called. Exit the thread");
break;
}
@@ -3750,7 +3781,7 @@ void AudioHardware::AudioSessionOutLPA::eventThreadEntry()
ALOGV("mEmptyQueueMutex unlocking: %d", __LINE__);
mEmptyQueueMutex.unlock();
ALOGV("mEmptyQueueMutex unlocked: %d", __LINE__);
if (mFilledQueue.empty() && mReachedEOS) {
if (mFilledQueue.empty() && mReachedEOS && mGenerateEOS) {
ALOGV("Posting the EOS to the observer player %p", mObserver);
mEosEventReceived = true;
if (mObserver != NULL) {
@@ -3789,6 +3820,7 @@ void AudioHardware::AudioSessionOutLPA::eventThreadEntry()
if ( ioctl(afd, AUDIO_STOP, 0) < 0 ) {
ALOGE("AUDIO_STOP failed");
}
mIsDriverStarted = false;
break;
}
break;
@@ -3823,22 +3855,16 @@ status_t AudioHardware::AudioSessionOutLPA::start( ) //TODO YM LPA removed start
{

ALOGV("LPA playback start");
if (mPaused) {

if (mPaused && mIsDriverStarted) {
mPaused = false;
if (ioctl(afd, AUDIO_PAUSE, 0) < 0) {
ALOGE("Resume:: LPA driver resume failed");
return UNKNOWN_ERROR;
}

if (mSeeking) {
mSeeking = false;
} else {
mPaused = false;
}

} else {
//get config, set config and AUDIO_START LPA driver
int sessionId = 0;
mPaused = false;
if ( afd >= 0 ) {
struct msm_audio_config config;
if ( ioctl(afd, AUDIO_GET_CONFIG, &config) < 0 ) {
@@ -3863,7 +3889,7 @@ status_t AudioHardware::AudioSessionOutLPA::start( ) //TODO YM LPA removed start
ALOGE("Driver start failed!");
return BAD_VALUE;
}
bufferAlloc();
mIsDriverStarted = true;
if (timeStarted == 0)
timeStarted = nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_MONOTONIC));// Needed
}
@@ -3890,7 +3916,6 @@ status_t AudioHardware::AudioSessionOutLPA::drain()
status_t AudioHardware::AudioSessionOutLPA::flush()
{
ALOGV("LPA playback flush ");
Mutex::Autolock autoLock(mLock);
int err;

// 2.) Add all the available buffers to Empty Queue (Maintain order)
@@ -3907,25 +3932,35 @@ status_t AudioHardware::AudioSessionOutLPA::flush()
mFilledQueueMutex.unlock();
ALOGV("Transferred all the buffers from Filled queue to "
"Empty queue to handle seek");
ALOGV("mPaused %d mEosEventReceived %d", mPaused, mEosEventReceived);
mReachedEOS = false;
if (!mPaused && !mEosEventReceived) {

if (ioctl(afd, AUDIO_PAUSE, 1) < 0) {
ALOGE("Audio Pause failed");
return UNKNOWN_ERROR;
if (!mPaused) {
if (!mEosEventReceived) {
if (ioctl(afd, AUDIO_PAUSE, 1) < 0) {
ALOGE("Audio Pause failed");
return UNKNOWN_ERROR;
}
mSkipWrite = true;
if (ioctl(afd, AUDIO_FLUSH, 0) < 0) {
ALOGE("Audio Flush failed");
return UNKNOWN_ERROR;
}
}
} else {
timeStarted = 0;
mSkipWrite = true;
if (ioctl(afd, AUDIO_FLUSH, 0) < 0) {
ALOGE("Audio Flush failed");
return UNKNOWN_ERROR;
return UNKNOWN_ERROR;
}
if (ioctl(afd, AUDIO_PAUSE, 1) < 0) {
ALOGE("Audio Pause failed");
return UNKNOWN_ERROR;
}

} else {
mSeeking = true;
timeStarted = 0;
}
mEosEventReceived = false;
//4.) Skip the current write from the decoder and signal to the Write get
// the next set of data from the decoder
mSkipWrite = true;
mWriteCv.signal();
return NO_ERROR;
}
@@ -3936,9 +3971,6 @@ status_t AudioHardware::AudioSessionOutLPA::stop()
// close all the existing PCM devices
mSkipWrite = true;
mWriteCv.signal();

reset();

return NO_ERROR;
}

@@ -3960,11 +3992,13 @@ status_t AudioHardware::AudioSessionOutLPA::getNextWriteTimestamp(int64_t *time
void AudioHardware::AudioSessionOutLPA::reset()
{
ALOGD("AudioSessionOutLPA::reset()");
mGenerateEOS = false;
//Close the LPA driver
ioctl(afd,AUDIO_STOP,0);
mIsDriverStarted = false;
requestAndWaitForEventThreadExit();
status_t status = NO_ERROR;
bufferDeAlloc();
//Close the LPA driver
ioctl(afd,AUDIO_STOP,0);
::close(afd);
ALOGD("AudioSessionOutLPA::reset() complete");
}
@@ -3997,7 +4031,7 @@ status_t AudioHardware::AudioSessionOutLPA::isBufferAvailable(int *isAvail) {
Mutex::Autolock autoLock(mLock);
ALOGV("isBufferAvailable Empty Queue size() = %d, Filled Queue size() = %d ",
mEmptyQueue.size(),mFilledQueue.size());

*isAvail = false;
// 1.) Wait till a empty buffer is available in the Empty buffer queue
mEmptyQueueMutex.lock();
if (mEmptyQueue.empty()) {
@@ -4011,7 +4045,7 @@ status_t AudioHardware::AudioSessionOutLPA::isBufferAvailable(int *isAvail) {
mEmptyQueueMutex.unlock();
return NO_ERROR;
}
ALOGV("isBufferAvailable: received a signal to wake up");
ALOGV("Write: received a signal to wake up");
}
mEmptyQueueMutex.unlock();

@@ -30,7 +30,7 @@

extern "C" {
#include <linux/msm_audio.h>
#include <linux/msm_ion.h>
#include <linux/ion.h>
#include <linux/msm_audio_voicememo.h>
#ifdef QCOM_VOIP_ENABLED
#include <linux/msm_audio_mvs.h>
@@ -69,8 +69,8 @@ using android::Condition;
#define MBADRC_DISABLE 0xFFEF
#define SRS_ENABLE 0x0020
#define SRS_DISABLE 0xFFDF
#define LPA_BUFFER_SIZE 256*1024
#define BUFFER_COUNT 4
#define LPA_BUFFER_SIZE 512*1024
#define BUFFER_COUNT 2

#define AGC_ENABLE 0x0001
#define NS_ENABLE 0x0002
@@ -250,7 +250,7 @@ class AudioHardware : public AudioHardwareBase
status_t dumpInternals(int fd, const Vector<String16>& args);
uint32_t getInputSampleRate(uint32_t sampleRate);
bool checkOutputStandby();
status_t doRouting(AudioStreamInMSM72xx *input);
status_t doRouting(AudioStreamInMSM72xx *input, int outputDevice = 0);
#ifdef QCOM_FM_ENABLED
status_t enableFM();
status_t disableFM();
@@ -426,6 +426,8 @@ class AudioSessionOutLPA : public AudioStreamOut
uint32_t mStreamVol;

bool mPaused;
bool mIsDriverStarted;
bool mGenerateEOS;
bool mSeeking;
bool mReachedEOS;
bool mSkipWrite;

0 comments on commit 3b1cab1

Please sign in to comment.
You can’t perform that action at this time.