summaryrefslogtreecommitdiffstats
path: root/libs/audioflinger
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:23 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:23 -0800
commitb798689749c64baba81f02e10cf2157c747d6b46 (patch)
treeda394a395ddb1a6cf69193314846b03fe47a397e /libs/audioflinger
parentf013e1afd1e68af5e3b868c26a653bbfb39538f8 (diff)
downloadframeworks_base-b798689749c64baba81f02e10cf2157c747d6b46.zip
frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.gz
frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.bz2
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'libs/audioflinger')
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp49
-rw-r--r--libs/audioflinger/A2dpAudioInterface.h12
-rw-r--r--libs/audioflinger/AudioDumpInterface.cpp16
-rw-r--r--libs/audioflinger/AudioDumpInterface.h2
-rw-r--r--libs/audioflinger/AudioFlinger.cpp135
-rw-r--r--libs/audioflinger/AudioFlinger.h3
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.cpp12
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.h2
-rw-r--r--libs/audioflinger/AudioHardwareStub.cpp10
-rw-r--r--libs/audioflinger/AudioHardwareStub.h2
10 files changed, 125 insertions, 118 deletions
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index d54795c..b2a8e96 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -79,11 +79,6 @@ AudioStreamIn* A2dpAudioInterface::openInputStream(
return NULL;
}
-status_t A2dpAudioInterface::standby()
-{
- return 0;
-}
-
status_t A2dpAudioInterface::setMicMute(bool state)
{
return 0;
@@ -123,8 +118,8 @@ status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
// ----------------------------------------------------------------------------
A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
- mFd(-1), mStartCount(0), mRetryCount(0), mData(NULL),
- mInitialized(false), mBufferRemaining(0)
+ mFd(-1), mStandby(false), mStartCount(0), mRetryCount(0), mData(NULL),
+ mInitialized(false)
{
}
@@ -155,26 +150,50 @@ A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
{
+ status_t status = NO_INIT;
+ size_t remaining = bytes;
+
if (!mInitialized) {
- int ret = a2dp_init("00:00:00:00:00:00", 44100, 2, &mData);
- if (ret)
- return ret;
+ status = a2dp_init("00:00:00:00:00:00", 44100, 2, &mData);
+ if (status < 0) {
+ LOGE("a2dp_init failed err: %d\n", status);
+ goto Error;
+ }
mInitialized = true;
}
- size_t remaining = bytes;
while (remaining > 0) {
- int written = a2dp_write(mData, buffer, remaining);
- remaining -= written;
- buffer = ((char *)buffer) + written;
+ status = a2dp_write(mData, buffer, remaining);
+ if (status <= 0) {
+ LOGE("a2dp_write failed err: %d\n", status);
+ goto Error;
+ }
+ remaining -= status;
+ buffer = ((char *)buffer) + status;
}
+
+ mStandby = false;
return bytes;
+
+Error:
+ // Simulate audio output timing in case of error
+ usleep(bytes * 1000000 / frameSize() / sampleRate());
+
+ return status;
}
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
{
- return 0;
+ int result = 0;
+
+ if (!mStandby) {
+ result = a2dp_stop(mData);
+ if (result == 0)
+ mStandby = true;
+ }
+
+ return result;
}
status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 03bf933..b8119a1 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -35,7 +35,6 @@ public:
A2dpAudioInterface();
virtual ~A2dpAudioInterface();
virtual status_t initCheck();
- virtual status_t standby();
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);
@@ -74,11 +73,11 @@ private:
int channelCount,
uint32_t sampleRate);
virtual uint32_t sampleRate() const { return 44100; }
- // must be 32-bit aligned - driver only seems to like 4800
- virtual size_t bufferSize() const { return 5120; }
+ // SBC codec wants a multiple of 512
+ virtual size_t bufferSize() const { return 512 * 30; }
virtual int channelCount() const { return 2; }
virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return 0; }
+ virtual uint32_t latency() const { return ((1000*channelCount()*bufferSize())/frameSize())/sampleRate() + 200; }
virtual status_t setVolume(float volume) { return INVALID_OPERATION; }
virtual ssize_t write(const void* buffer, size_t bytes);
status_t standby();
@@ -86,14 +85,11 @@ private:
private:
int mFd;
+ bool mStandby;
int mStartCount;
int mRetryCount;
void* mData;
bool mInitialized;
-
-#define kBufferSize 50000
- char mBuffer[kBufferSize];
- int mBufferRemaining;
};
Mutex mLock;
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
index 8eee9cc..b4940cb 100644
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -49,14 +49,6 @@ AudioDumpInterface::~AudioDumpInterface()
}
-status_t AudioDumpInterface::standby()
-{
- if(mStreamOut) mStreamOut->Close();
- gFirst = true;
- return mFinalInterface->standby();
-}
-
-
AudioStreamOut* AudioDumpInterface::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
@@ -106,6 +98,14 @@ ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
return ret;
}
+status_t AudioStreamOutDump::standby()
+{
+ Close();
+ gFirst = true;
+ return mFinalStream->standby();
+}
+
+
void AudioStreamOutDump::Close(void)
{
if(mOutFile) {
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index a65e56a..82b5250 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -40,6 +40,7 @@ public:
virtual uint32_t latency() const { return mFinalStream->latency(); }
virtual status_t setVolume(float volume)
{ return mFinalStream->setVolume(volume); }
+ virtual status_t standby();
virtual status_t dump(int fd, const Vector<String16>& args) { return mFinalStream->dump(fd, args); }
void Close(void);
@@ -54,7 +55,6 @@ class AudioDumpInterface : public AudioHardwareBase
public:
AudioDumpInterface(AudioHardwareInterface* hw);
- virtual status_t standby();
virtual AudioStreamOut* openOutputStream(
int format=0,
int channelCount=0,
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 53b18ad..d4692ad 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -100,11 +100,11 @@ static bool settingsAllowed() {
AudioFlinger::AudioFlinger()
: BnAudioFlinger(), Thread(false),
mMasterVolume(0), mMasterMute(true), mHardwareAudioMixer(0), mA2dpAudioMixer(0),
- mAudioMixer(0), mAudioHardware(0), mA2dpAudioInterface(0),
- mHardwareOutput(0), mA2dpOutput(0), mOutput(0), mAudioRecordThread(0),
- mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0),
- mMixBuffer(0), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0),
- mStandby(false), mInWrite(false)
+ mAudioMixer(0), mAudioHardware(0), mA2dpAudioInterface(0), mHardwareOutput(0),
+ mA2dpOutput(0), mOutput(0), mRequestedOutput(0), mAudioRecordThread(0),
+ mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
+ mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
+ mInWrite(false)
{
mHardwareStatus = AUDIO_HW_IDLE;
mAudioHardware = AudioHardwareInterface::create();
@@ -116,9 +116,9 @@ AudioFlinger::AudioFlinger()
mHardwareOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
mHardwareStatus = AUDIO_HW_IDLE;
if (mHardwareOutput) {
- mSampleRate = mHardwareOutput->sampleRate();
- mHardwareAudioMixer = new AudioMixer(getOutputFrameCount(mHardwareOutput), mSampleRate);
- setOutput(mHardwareOutput);
+ mHardwareAudioMixer = new AudioMixer(getOutputFrameCount(mHardwareOutput), mHardwareOutput->sampleRate());
+ mRequestedOutput = mHardwareOutput;
+ doSetOutput(mHardwareOutput);
// FIXME - this should come from settings
setMasterVolume(1.0f);
@@ -159,7 +159,6 @@ AudioFlinger::AudioFlinger()
}
char value[PROPERTY_VALUE_MAX];
- // FIXME: What property should this be???
property_get("ro.audio.silent", value, "0");
if (atoi(value)) {
LOGD("Silence is golden");
@@ -173,9 +172,8 @@ AudioFlinger::~AudioFlinger()
mAudioRecordThread->exit();
mAudioRecordThread.clear();
}
- delete mOutput;
- delete mA2dpOutput;
delete mAudioHardware;
+ // deleting mA2dpAudioInterface also deletes mA2dpOutput;
delete mA2dpAudioInterface;
delete [] mMixBuffer;
delete mHardwareAudioMixer;
@@ -184,26 +182,22 @@ AudioFlinger::~AudioFlinger()
void AudioFlinger::setOutput(AudioStreamOut* output)
{
- // lock on mOutputLock to prevent threadLoop() from starving us
- Mutex::Autolock _l2(mOutputLock);
-
- // to synchronize with threadLoop()
- Mutex::Autolock _l(mLock);
+ mRequestedOutput = output;
+}
- if (mOutput != output) {
- mSampleRate = output->sampleRate();
- mChannelCount = output->channelCount();
-
- // FIXME - Current mixer implementation only supports stereo output
- if (mChannelCount == 1) {
- LOGE("Invalid audio hardware channel count");
- }
- mFormat = output->format();
- mFrameCount = getOutputFrameCount(output);
-
- mAudioMixer = (output == mA2dpOutput ? mA2dpAudioMixer : mHardwareAudioMixer);
- mOutput = output;
+void AudioFlinger::doSetOutput(AudioStreamOut* output)
+{
+ mSampleRate = output->sampleRate();
+ mChannelCount = output->channelCount();
+
+ // FIXME - Current mixer implementation only supports stereo output
+ if (mChannelCount == 1) {
+ LOGE("Invalid audio hardware channel count");
}
+ mFormat = output->format();
+ mFrameCount = getOutputFrameCount(output);
+ mAudioMixer = (output == mA2dpOutput ? mA2dpAudioMixer : mHardwareAudioMixer);
+ mOutput = output;
}
size_t AudioFlinger::getOutputFrameCount(AudioStreamOut* output)
@@ -330,21 +324,11 @@ bool AudioFlinger::threadLoop()
Vector< sp<Track> > tracksToRemove;
size_t enabledTracks = 0;
nsecs_t standbyTime = systemTime();
- AudioMixer* mixer = 0;
- size_t frameCount = 0;
- int channelCount = 0;
- uint32_t sampleRate = 0;
- AudioStreamOut* output = 0;
do {
enabledTracks = 0;
{ // scope for the mLock
- // locking briefly on the secondary mOutputLock is necessary to avoid
- // having this thread starve the thread that called setOutput()
- mOutputLock.lock();
- mOutputLock.unlock();
-
Mutex::Autolock _l(mLock);
const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -354,7 +338,7 @@ bool AudioFlinger::threadLoop()
LOGV("Audio hardware entering standby\n");
mHardwareStatus = AUDIO_HW_STANDBY;
if (!mStandby) {
- mAudioHardware->standby();
+ mOutput->standby();
mStandby = true;
}
mHardwareStatus = AUDIO_HW_IDLE;
@@ -366,15 +350,16 @@ bool AudioFlinger::threadLoop()
continue;
}
- // get active mixer and output parameter while the lock is held and keep them
- // consistent till the next loop.
-
- mixer = audioMixer();
- frameCount = mFrameCount;
- channelCount = mChannelCount;
- sampleRate = mSampleRate;
- output = mOutput;
-
+ // check for change in output
+ if (mRequestedOutput != mOutput) {
+
+ // put current output into standby mode
+ if (mOutput) mOutput->standby();
+
+ // change output
+ doSetOutput(mRequestedOutput);
+ }
+
// find out which tracks need to be processed
size_t count = activeTracks.size();
for (size_t i=0 ; i<count ; i++) {
@@ -386,7 +371,7 @@ bool AudioFlinger::threadLoop()
// The first time a track is added we wait
// for all its buffers to be filled before processing it
- mixer->setActiveTrack(track->name());
+ mAudioMixer->setActiveTrack(track->name());
if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
!track->isPaused())
{
@@ -412,8 +397,8 @@ bool AudioFlinger::threadLoop()
}
// XXX: these things DON'T need to be done each time
- mixer->setBufferProvider(track);
- mixer->enable(AudioMixer::MIXING);
+ mAudioMixer->setBufferProvider(track);
+ mAudioMixer->enable(AudioMixer::MIXING);
int param;
if ( track->mFillingUpStatus == Track::FS_FILLED) {
@@ -428,15 +413,15 @@ bool AudioFlinger::threadLoop()
} else {
param = AudioMixer::RAMP_VOLUME;
}
- mixer->setParameter(param, AudioMixer::VOLUME0, left);
- mixer->setParameter(param, AudioMixer::VOLUME1, right);
- mixer->setParameter(
+ mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
+ mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
+ mAudioMixer->setParameter(
AudioMixer::TRACK,
AudioMixer::FORMAT, track->format());
- mixer->setParameter(
+ mAudioMixer->setParameter(
AudioMixer::TRACK,
AudioMixer::CHANNEL_COUNT, track->channelCount());
- mixer->setParameter(
+ mAudioMixer->setParameter(
AudioMixer::RESAMPLE,
AudioMixer::SAMPLE_RATE,
int(cblk->sampleRate));
@@ -463,7 +448,7 @@ bool AudioFlinger::threadLoop()
}
}
// LOGV("disable(%d)", track->name());
- mixer->disable(AudioMixer::MIXING);
+ mAudioMixer->disable(AudioMixer::MIXING);
}
}
@@ -475,27 +460,27 @@ bool AudioFlinger::threadLoop()
mActiveTracks.remove(track);
if (track->isTerminated()) {
mTracks.remove(track);
- mixer->deleteTrackName(track->mName);
+ mAudioMixer->deleteTrackName(track->mName);
}
}
}
}
if (LIKELY(enabledTracks)) {
// mix buffers...
- mixer->process(curBuf);
+ mAudioMixer->process(curBuf);
// output audio to hardware
mLastWriteTime = systemTime();
mInWrite = true;
- size_t mixBufferSize = frameCount*channelCount*sizeof(int16_t);
- output->write(curBuf, mixBufferSize);
+ size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
+ mOutput->write(curBuf, mixBufferSize);
mNumWrites++;
mInWrite = false;
mStandby = false;
nsecs_t temp = systemTime();
standbyTime = temp + kStandbyTimeInNsecs;
nsecs_t delta = temp - mLastWriteTime;
- nsecs_t maxPeriod = seconds(frameCount) / sampleRate * 2;
+ nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
if (delta > maxPeriod) {
LOGW("write blocked for %llu msecs", ns2ms(delta));
mNumDelayedWrites++;
@@ -653,6 +638,8 @@ status_t AudioFlinger::setMasterVolume(float value)
status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
{
+ status_t err = NO_ERROR;
+
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
@@ -677,16 +664,20 @@ status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
}
#endif
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_GET_ROUTING;
- uint32_t r;
- uint32_t err = mAudioHardware->getRouting(mode, &r);
- if (err == NO_ERROR) {
- r = (r & ~mask) | (routes & mask);
- mHardwareStatus = AUDIO_HW_SET_ROUTING;
- err = mAudioHardware->setRouting(mode, r);
+ // do nothing if only A2DP routing is affected
+ mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
+ if (mask) {
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_GET_ROUTING;
+ uint32_t r;
+ err = mAudioHardware->getRouting(mode, &r);
+ if (err == NO_ERROR) {
+ r = (r & ~mask) | (routes & mask);
+ mHardwareStatus = AUDIO_HW_SET_ROUTING;
+ err = mAudioHardware->setRouting(mode, r);
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
}
- mHardwareStatus = AUDIO_HW_IDLE;
return err;
}
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index d9f7b49..7c84e62 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -150,6 +150,7 @@ private:
virtual ~AudioFlinger();
void setOutput(AudioStreamOut* output);
+ void doSetOutput(AudioStreamOut* output);
size_t getOutputFrameCount(AudioStreamOut* output);
// Internal dump utilites.
@@ -450,7 +451,6 @@ private:
mutable Mutex mHardwareLock;
mutable Mutex mLock;
- mutable Mutex mOutputLock;
mutable Condition mWaitWorkCV;
DefaultKeyedVector< pid_t, wp<Client> > mClients;
SortedVector< wp<Track> > mActiveTracks;
@@ -468,6 +468,7 @@ private:
AudioStreamOut* mHardwareOutput;
AudioStreamOut* mA2dpOutput;
AudioStreamOut* mOutput;
+ AudioStreamOut* mRequestedOutput;
sp<AudioRecordThread> mAudioRecordThread;
uint32_t mSampleRate;
size_t mFrameCount;
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index e6a163b..e455186 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -61,12 +61,6 @@ status_t AudioHardwareGeneric::initCheck()
return NO_INIT;
}
-status_t AudioHardwareGeneric::standby()
-{
- // Implement: audio hardware to standby mode
- return NO_ERROR;
-}
-
AudioStreamOut* AudioHardwareGeneric::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
@@ -215,6 +209,12 @@ ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
return ssize_t(::write(mFd, buffer, bytes));
}
+status_t AudioStreamOutGeneric::standby()
+{
+ // Implement: audio hardware to standby mode
+ return NO_ERROR;
+}
+
status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index a2342cd..bc006b8 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -50,6 +50,7 @@ public:
virtual uint32_t latency() const { return 0; }
virtual status_t setVolume(float volume) { return INVALID_OPERATION; }
virtual ssize_t write(const void* buffer, size_t bytes);
+ virtual status_t standby();
virtual status_t dump(int fd, const Vector<String16>& args);
private:
@@ -92,7 +93,6 @@ public:
AudioHardwareGeneric();
virtual ~AudioHardwareGeneric();
virtual status_t initCheck();
- virtual status_t standby();
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index d309902..e9f3d69 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -41,11 +41,6 @@ status_t AudioHardwareStub::initCheck()
return NO_ERROR;
}
-status_t AudioHardwareStub::standby()
-{
- return NO_ERROR;
-}
-
AudioStreamOut* AudioHardwareStub::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
@@ -125,6 +120,11 @@ ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
return bytes;
}
+status_t AudioStreamOutStub::standby()
+{
+ return NO_ERROR;
+}
+
status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index 5316d60..7ec5b95 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -37,6 +37,7 @@ public:
virtual uint32_t latency() const { return 0; }
virtual status_t setVolume(float volume) { return NO_ERROR; }
virtual ssize_t write(const void* buffer, size_t bytes);
+ virtual status_t standby();
virtual status_t dump(int fd, const Vector<String16>& args);
};
@@ -59,7 +60,6 @@ public:
AudioHardwareStub();
virtual ~AudioHardwareStub();
virtual status_t initCheck();
- virtual status_t standby();
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);