diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
commit | b798689749c64baba81f02e10cf2157c747d6b46 (patch) | |
tree | da394a395ddb1a6cf69193314846b03fe47a397e /libs/audioflinger | |
parent | f013e1afd1e68af5e3b868c26a653bbfb39538f8 (diff) | |
download | frameworks_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.cpp | 49 | ||||
-rw-r--r-- | libs/audioflinger/A2dpAudioInterface.h | 12 | ||||
-rw-r--r-- | libs/audioflinger/AudioDumpInterface.cpp | 16 | ||||
-rw-r--r-- | libs/audioflinger/AudioDumpInterface.h | 2 | ||||
-rw-r--r-- | libs/audioflinger/AudioFlinger.cpp | 135 | ||||
-rw-r--r-- | libs/audioflinger/AudioFlinger.h | 3 | ||||
-rw-r--r-- | libs/audioflinger/AudioHardwareGeneric.cpp | 12 | ||||
-rw-r--r-- | libs/audioflinger/AudioHardwareGeneric.h | 2 | ||||
-rw-r--r-- | libs/audioflinger/AudioHardwareStub.cpp | 10 | ||||
-rw-r--r-- | libs/audioflinger/AudioHardwareStub.h | 2 |
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); |