diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/Android.mk | 4 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 121 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 6 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.cpp | 392 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.h | 29 | ||||
-rw-r--r-- | services/audioflinger/AudioPolicyService.cpp | 1 | ||||
-rw-r--r-- | services/audioflinger/AudioPolicyService.h | 3 |
7 files changed, 227 insertions, 329 deletions
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index fa49592..52834db 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -11,9 +11,11 @@ LOCAL_SRC_FILES:= \ AudioPolicyService.cpp LOCAL_C_INCLUDES := \ - system/media/audio_effects/include + system/media/audio_effects/include \ + system/media/audio_utils/include LOCAL_SHARED_LIBRARIES := \ + libaudioutils \ libcutils \ libutils \ libbinder \ diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index b48f23d..2090f1b 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -54,6 +54,8 @@ #include <audio_effects/effect_ns.h> #include <audio_effects/effect_aec.h> +#include <audio_utils/primitives.h> + #include <cpustats/ThreadCpuUsage.h> #include <powermanager/PowerManager.h> // #define DEBUG_CPU_USAGE 10 // log statistics every n wall clock seconds @@ -63,8 +65,8 @@ namespace android { -static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n"; -static const char* kHardwareLockedString = "Hardware lock is taken\n"; +static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n"; +static const char kHardwareLockedString[] = "Hardware lock is taken\n"; //static const nsecs_t kStandbyTimeInNsecs = seconds(3); static const float MAX_GAIN = 4096.0f; @@ -80,14 +82,16 @@ static const int8_t kMaxTrackStartupRetries = 50; static const int8_t kMaxTrackRetriesDirect = 2; static const int kDumpLockRetries = 50; -static const int kDumpLockSleep = 20000; +static const int kDumpLockSleepUs = 20000; -static const nsecs_t kWarningThrottle = seconds(5); +// don't warn about blocked writes or record buffer overflows more often than this +static const nsecs_t kWarningThrottleNs = seconds(5); // RecordThread loop sleep time upon application overrun or audio HAL read error static const int kRecordThreadSleepUs = 5000; -static const nsecs_t kSetParametersTimeout = seconds(2); +// maximum time to wait for setParameters to complete +static const nsecs_t kSetParametersTimeoutNs = seconds(2); // minimum sleep time for the mixer thread loop when tracks are active but in underrun static const uint32_t kMinThreadSleepTimeUs = 5000; @@ -147,7 +151,7 @@ out: return rc; } -static const char *audio_interfaces[] = { +static const char * const audio_interfaces[] = { "primary", "a2dp", "usb", @@ -158,7 +162,7 @@ static const char *audio_interfaces[] = { AudioFlinger::AudioFlinger() : BnAudioFlinger(), - mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), + mPrimaryHardwareDev(NULL), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), mBtNrecIsOff(false) { } @@ -320,7 +324,7 @@ static bool tryLock(Mutex& mutex) locked = true; break; } - usleep(kDumpLockSleep); + usleep(kDumpLockSleepUs); } return locked; } @@ -395,7 +399,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( int lSessionId; if (streamType >= AUDIO_STREAM_CNT) { - LOGE("invalid stream type"); + LOGE("createTrack() invalid stream type %d", streamType); lStatus = BAD_VALUE; goto Exit; } @@ -427,6 +431,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( // prevent same audio session on different output threads uint32_t sessions = t->hasAudioSession(*sessionId); if (sessions & PlaybackThread::TRACK_SESSION) { + LOGE("createTrack() session ID %d already in use", *sessionId); lStatus = BAD_VALUE; goto Exit; } @@ -657,6 +662,7 @@ status_t AudioFlinger::setStreamVolume(int stream, float value, int output) } if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) { + LOGE("setStreamVolume() invalid stream %d", stream); return BAD_VALUE; } @@ -691,6 +697,7 @@ status_t AudioFlinger::setStreamMute(int stream, bool muted) if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT || uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) { + LOGE("setStreamMute() invalid stream %d", stream); return BAD_VALUE; } @@ -988,7 +995,6 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int i AudioFlinger::ThreadBase::~ThreadBase() { mParamCond.broadcast(); - mNewParameters.clear(); // do not lock the mutex in destructor releaseWakeLock_l(); if (mPowerManager != 0) { @@ -999,7 +1005,7 @@ AudioFlinger::ThreadBase::~ThreadBase() void AudioFlinger::ThreadBase::exit() { - // keep a strong ref on ourself so that we wont get + // keep a strong ref on ourself so that we won't get // destroyed in the middle of requestExitAndWait() sp <ThreadBase> strongMe = this; @@ -1044,7 +1050,7 @@ status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs) mWaitWorkCV.signal(); // wait condition with timeout in case the thread loop has exited // before the request could be processed - if (mParamCond.waitRelative(mLock, kSetParametersTimeout) == NO_ERROR) { + if (mParamCond.waitRelative(mLock, kSetParametersTimeoutNs) == NO_ERROR) { status = mParamStatus; mWaitWorkCV.signal(); } else { @@ -1062,9 +1068,9 @@ void AudioFlinger::ThreadBase::sendConfigEvent(int event, int param) // sendConfigEvent_l() must be called with ThreadBase::mLock held void AudioFlinger::ThreadBase::sendConfigEvent_l(int event, int param) { - ConfigEvent *configEvent = new ConfigEvent(); - configEvent->mEvent = event; - configEvent->mParam = param; + ConfigEvent configEvent; + configEvent.mEvent = event; + configEvent.mParam = param; mConfigEvents.add(configEvent); ALOGV("sendConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event, param); mWaitWorkCV.signal(); @@ -1075,15 +1081,14 @@ void AudioFlinger::ThreadBase::processConfigEvents() mLock.lock(); while(!mConfigEvents.isEmpty()) { ALOGV("processConfigEvents() remaining events %d", mConfigEvents.size()); - ConfigEvent *configEvent = mConfigEvents[0]; + ConfigEvent configEvent = mConfigEvents[0]; mConfigEvents.removeAt(0); // release mLock before locking AudioFlinger mLock: lock order is always // AudioFlinger then ThreadBase to avoid cross deadlock mLock.unlock(); mAudioFlinger->mLock.lock(); - audioConfigChanged_l(configEvent->mEvent, configEvent->mParam); + audioConfigChanged_l(configEvent.mEvent, configEvent.mParam); mAudioFlinger->mLock.unlock(); - delete configEvent; mLock.lock(); } mLock.unlock(); @@ -1130,7 +1135,7 @@ status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args snprintf(buffer, SIZE, " Index event param\n"); result.append(buffer); for (size_t i = 0; i < mConfigEvents.size(); i++) { - snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam); + snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i].mEvent, mConfigEvents[i].mParam); result.append(buffer); } result.append("\n"); @@ -1367,7 +1372,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge int id, uint32_t device) : ThreadBase(audioFlinger, id, device), - mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output), + mMixBuffer(NULL), mSuspended(0), mBytesWritten(0), mOutput(output), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false) { snprintf(mName, kNameLength, "AudioOut_%d", id); @@ -1526,8 +1531,10 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra for (size_t i = 0; i < mTracks.size(); ++i) { sp<Track> t = mTracks[i]; if (t != 0) { - if (sessionId == t->sessionId() && - strategy != AudioSystem::getStrategyForStream((audio_stream_type_t)t->type())) { + uint32_t actual = AudioSystem::getStrategyForStream((audio_stream_type_t)t->type()); + if (sessionId == t->sessionId() && strategy != actual) { + LOGE("createTrack_l() mismatched strategy; expected %u but found %u", + strategy, actual); lStatus = BAD_VALUE; goto Exit; } @@ -1832,7 +1839,7 @@ uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device) : PlaybackThread(audioFlinger, output, id, device), - mAudioMixer(0) + mAudioMixer(NULL) { mType = ThreadBase::MIXER; mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); @@ -1967,7 +1974,7 @@ bool AudioFlinger::MixerThread::threadLoop() // during mixing and effect process as the audio buffers could be deleted // or modified if an effect is created or deleted lockEffectChains_l(effectChains); - } + } if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { // mix buffers... @@ -2012,11 +2019,11 @@ bool AudioFlinger::MixerThread::threadLoop() } // sleepTime == 0 means we must write to audio hardware if (sleepTime == 0) { - for (size_t i = 0; i < effectChains.size(); i ++) { - effectChains[i]->process_l(); - } - // enable changes in effect chain - unlockEffectChains(effectChains); + for (size_t i = 0; i < effectChains.size(); i ++) { + effectChains[i]->process_l(); + } + // enable changes in effect chain + unlockEffectChains(effectChains); mLastWriteTime = systemTime(); mInWrite = true; mBytesWritten += mixBufferSize; @@ -2029,7 +2036,7 @@ bool AudioFlinger::MixerThread::threadLoop() nsecs_t delta = now - mLastWriteTime; if (!mStandby && delta > maxPeriod) { mNumDelayedWrites++; - if ((now - lastWarning) > kWarningThrottle) { + if ((now - lastWarning) > kWarningThrottleNs) { LOGW("write blocked for %llu msecs, %d delayed writes, thread %p", ns2ms(delta), mNumDelayedWrites, this); lastWarning = now; @@ -2197,7 +2204,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track // XXX: these things DON'T need to be done each time mAudioMixer->setBufferProvider(track); - mAudioMixer->enable(AudioMixer::MIXING); + mAudioMixer->enable(); mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left); mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right); @@ -2243,7 +2250,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track mixerStatus = MIXER_TRACKS_ENABLED; } } - mAudioMixer->disable(AudioMixer::MIXING); + mAudioMixer->disable(); } } @@ -2344,7 +2351,7 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() } if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { // do not accept frame count changes if tracks are open as the track buffer - // size depends on frame count and correct behavior would not be garantied + // size depends on frame count and correct behavior would not be guaranteed // if frame count is changed after track creation if (!mTracks.isEmpty()) { status = INVALID_OPERATION; @@ -2415,7 +2422,7 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() mParamCond.signal(); // wait for condition with time out in case the thread calling ThreadBase::setParameters() // already timed out waiting for the status and will never signal the condition. - mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout); + mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs); } return reconfig; } @@ -2455,14 +2462,6 @@ AudioFlinger::DirectOutputThread::~DirectOutputThread() { } - -static inline int16_t clamp16(int32_t sample) -{ - if ((sample>>15) ^ (sample>>31)) - sample = 0x7FFF ^ (sample>>31); - return sample; -} - static inline int32_t mul(int16_t in, int16_t v) { @@ -2766,7 +2765,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() while (frameCount) { buffer.frameCount = frameCount; activeTrack->getNextBuffer(&buffer); - if (UNLIKELY(buffer.raw == 0)) { + if (UNLIKELY(buffer.raw == NULL)) { memset(curBuf, 0, frameCount * mFrameSize); break; } @@ -2891,7 +2890,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameters_l() mParamCond.signal(); // wait for condition with time out in case the thread calling ThreadBase::setParameters() // already timed out waiting for the status and will never signal the condition. - mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout); + mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs); } return reconfig; } @@ -3264,7 +3263,7 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase() void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer) { - buffer->raw = 0; + buffer->raw = NULL; mFrameCount = buffer->frameCount; step(); buffer->frameCount = 0; @@ -3457,14 +3456,14 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider: } buffer->raw = getBuffer(s, framesReq); - if (buffer->raw == 0) goto getNextBuffer_exit; + if (buffer->raw == NULL) goto getNextBuffer_exit; buffer->frameCount = framesReq; return NO_ERROR; } getNextBuffer_exit: - buffer->raw = 0; + buffer->raw = NULL; buffer->frameCount = 0; ALOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get()); return NOT_ENOUGH_DATA; @@ -3705,14 +3704,14 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi } buffer->raw = getBuffer(s, framesReq); - if (buffer->raw == 0) goto getNextBuffer_exit; + if (buffer->raw == NULL) goto getNextBuffer_exit; buffer->frameCount = framesReq; return NO_ERROR; } getNextBuffer_exit: - buffer->raw = 0; + buffer->raw = NULL; buffer->frameCount = 0; return NOT_ENOUGH_DATA; } @@ -4217,7 +4216,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device) : ThreadBase(audioFlinger, id, device), - mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0) + mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL) { mType = ThreadBase::RECORD; @@ -4232,7 +4231,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::RecordThread::~RecordThread() { delete[] mRsmpInBuffer; - if (mResampler != 0) { + if (mResampler != NULL) { delete mResampler; delete[] mRsmpOutBuffer; } @@ -4326,7 +4325,7 @@ bool AudioFlinger::RecordThread::threadLoop() buffer.frameCount = mFrameCount; if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) { size_t framesOut = buffer.frameCount; - if (mResampler == 0) { + if (mResampler == NULL) { // no resampling while (framesOut) { size_t framesIn = mFrameCount - mRsmpInIndex; @@ -4391,7 +4390,7 @@ bool AudioFlinger::RecordThread::threadLoop() // ditherAndClamp() works as long as all buffers returned by mActiveTrack->getNextBuffer() // are 32 bit aligned which should be always true. if (mChannelCount == 2 && mReqChannelCount == 1) { - AudioMixer::ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut); + ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut); // the resampler always outputs stereo samples: do post stereo to mono conversion int16_t *src = (int16_t *)mRsmpOutBuffer; int16_t *dst = buffer.i16; @@ -4400,7 +4399,7 @@ bool AudioFlinger::RecordThread::threadLoop() src += 2; } } else { - AudioMixer::ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut); + ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut); } } @@ -4411,7 +4410,7 @@ bool AudioFlinger::RecordThread::threadLoop() else { if (!mActiveTrack->setOverflow()) { nsecs_t now = systemTime(); - if ((now - lastWarning) > kWarningThrottle) { + if ((now - lastWarning) > kWarningThrottleNs) { LOGW("RecordThread: buffer overflow"); lastWarning = now; } @@ -4584,7 +4583,7 @@ status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args) result.append(buffer); snprintf(buffer, SIZE, "In size: %d\n", mInputBytes); result.append(buffer); - snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0)); + snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != NULL)); result.append(buffer); snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount); result.append(buffer); @@ -4619,7 +4618,7 @@ status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* mInput->stream->common.standby(&mInput->stream->common); usleep(kRecordThreadSleepUs); } - buffer->raw = 0; + buffer->raw = NULL; buffer->frameCount = 0; return NOT_ENOUGH_DATA; } @@ -4734,7 +4733,7 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l() mParamCond.signal(); // wait for condition with time out in case the thread calling ThreadBase::setParameters() // already timed out waiting for the status and will never signal the condition. - mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout); + mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs); } return reconfig; } @@ -4782,7 +4781,7 @@ void AudioFlinger::RecordThread::readInputParameters() if (mRsmpInBuffer) delete mRsmpInBuffer; if (mRsmpOutBuffer) delete mRsmpOutBuffer; if (mResampler) delete mResampler; - mResampler = 0; + mResampler = NULL; mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common); mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common); @@ -6271,7 +6270,7 @@ void AudioFlinger::EffectModule::process() if (isProcessEnabled()) { // do 32 bit to 16 bit conversion for auxiliary effect input buffer if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { - AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32, + ditherAndClamp(mConfig.inputCfg.buffer.s32, mConfig.inputCfg.buffer.s32, mConfig.inputCfg.buffer.frameCount/2); } @@ -6376,7 +6375,7 @@ status_t AudioFlinger::EffectModule::configure() status_t cmdStatus; uint32_t size = sizeof(int); status_t status = (*mEffectInterface)->command(mEffectInterface, - EFFECT_CMD_CONFIGURE, + EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), &mConfig, &size, diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 6cafa7e..9707cf4 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -547,7 +547,7 @@ private: Condition mParamCond; Vector<String8> mNewParameters; status_t mParamStatus; - Vector<ConfigEvent *> mConfigEvents; + Vector<ConfigEvent> mConfigEvents; bool mStandby; int mId; bool mExiting; @@ -703,7 +703,7 @@ private: virtual status_t readyToRun(); virtual void onFirstRef(); - virtual status_t initCheck() const { return (mOutput == 0) ? NO_INIT : NO_ERROR; } + virtual status_t initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; } virtual uint32_t latency() const; @@ -980,7 +980,7 @@ private: virtual status_t readyToRun(); virtual void onFirstRef(); - virtual status_t initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; } + virtual status_t initCheck() const { return (mInput == NULL) ? NO_INIT : NO_ERROR; } sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l( const sp<AudioFlinger::Client>& client, uint32_t sampleRate, diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 1c5796d..89f7b65 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -18,6 +18,7 @@ #define LOG_TAG "AudioMixer" //#define LOG_NDEBUG 0 +#include <assert.h> #include <stdint.h> #include <string.h> #include <stdlib.h> @@ -30,67 +31,69 @@ #include <system/audio.h> +#include <audio_utils/primitives.h> + #include "AudioMixer.h" namespace android { -// ---------------------------------------------------------------------------- - -static inline int16_t clamp16(int32_t sample) -{ - if ((sample>>15) ^ (sample>>31)) - sample = 0x7FFF ^ (sample>>31); - return sample; -} // ---------------------------------------------------------------------------- AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate) : mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate) { + // AudioMixer is not yet capable of multi-channel beyond stereo + assert(2 == MAX_NUM_CHANNELS); mState.enabledTracks= 0; mState.needsChanged = 0; mState.frameCount = frameCount; - mState.outputTemp = 0; - mState.resampleTemp = 0; + mState.outputTemp = NULL; + mState.resampleTemp = NULL; mState.hook = process__nop; track_t* t = mState.tracks; - for (int i=0 ; i<32 ; i++) { + for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { t->needs = 0; t->volume[0] = UNITY_GAIN; t->volume[1] = UNITY_GAIN; + // no initialization needed + // t->prevVolume[0] + // t->prevVolume[1] t->volumeInc[0] = 0; t->volumeInc[1] = 0; t->auxLevel = 0; t->auxInc = 0; + // no initialization needed + // t->prevAuxLevel + // t->frameCount t->channelCount = 2; t->enabled = 0; t->format = 16; t->channelMask = AUDIO_CHANNEL_OUT_STEREO; t->buffer.raw = 0; - t->bufferProvider = 0; - t->hook = 0; - t->resampler = 0; + t->bufferProvider = NULL; + t->hook = NULL; + t->resampler = NULL; t->sampleRate = mSampleRate; - t->in = 0; + t->in = NULL; t->mainBuffer = NULL; t->auxBuffer = NULL; t++; } } - AudioMixer::~AudioMixer() - { - track_t* t = mState.tracks; - for (int i=0 ; i<32 ; i++) { - delete t->resampler; - t++; - } - delete [] mState.outputTemp; - delete [] mState.resampleTemp; - } +AudioMixer::~AudioMixer() +{ + track_t* t = mState.tracks; + for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { + delete t->resampler; + t++; + } + delete [] mState.outputTemp; + delete [] mState.resampleTemp; +} - int AudioMixer::getTrackName() - { +int AudioMixer::getTrackName() +{ uint32_t names = mTrackNames; uint32_t mask = 1; int n = 0; @@ -104,142 +107,131 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate) return TRACK0 + n; } return -1; - } +} - void AudioMixer::invalidateState(uint32_t mask) - { +void AudioMixer::invalidateState(uint32_t mask) +{ if (mask) { mState.needsChanged |= mask; mState.hook = process__validate; } } - void AudioMixer::deleteTrackName(int name) - { +void AudioMixer::deleteTrackName(int name) +{ name -= TRACK0; - if (uint32_t(name) < MAX_NUM_TRACKS) { - ALOGV("deleteTrackName(%d)", name); - track_t& track(mState.tracks[ name ]); - if (track.enabled != 0) { - track.enabled = 0; - invalidateState(1<<name); - } - if (track.resampler) { - // delete the resampler - delete track.resampler; - track.resampler = 0; - track.sampleRate = mSampleRate; - invalidateState(1<<name); - } - track.volumeInc[0] = 0; - track.volumeInc[1] = 0; - mTrackNames &= ~(1<<name); + assert(uint32_t(name) < MAX_NUM_TRACKS); + ALOGV("deleteTrackName(%d)", name); + track_t& track(mState.tracks[ name ]); + if (track.enabled != 0) { + track.enabled = 0; + invalidateState(1<<name); } - } + if (track.resampler) { + // delete the resampler + delete track.resampler; + track.resampler = NULL; + track.sampleRate = mSampleRate; + invalidateState(1<<name); + } + track.volumeInc[0] = 0; + track.volumeInc[1] = 0; + mTrackNames &= ~(1<<name); +} -status_t AudioMixer::enable(int name) +void AudioMixer::enable() { - switch (name) { - case MIXING: { - if (mState.tracks[ mActiveTrack ].enabled != 1) { - mState.tracks[ mActiveTrack ].enabled = 1; - ALOGV("enable(%d)", mActiveTrack); - invalidateState(1<<mActiveTrack); - } - } break; - default: - return NAME_NOT_FOUND; + if (mState.tracks[ mActiveTrack ].enabled != 1) { + mState.tracks[ mActiveTrack ].enabled = 1; + ALOGV("enable(%d)", mActiveTrack); + invalidateState(1<<mActiveTrack); } - return NO_ERROR; } -status_t AudioMixer::disable(int name) +void AudioMixer::disable() { - switch (name) { - case MIXING: { - if (mState.tracks[ mActiveTrack ].enabled != 0) { - mState.tracks[ mActiveTrack ].enabled = 0; - ALOGV("disable(%d)", mActiveTrack); - invalidateState(1<<mActiveTrack); - } - } break; - default: - return NAME_NOT_FOUND; + if (mState.tracks[ mActiveTrack ].enabled != 0) { + mState.tracks[ mActiveTrack ].enabled = 0; + ALOGV("disable(%d)", mActiveTrack); + invalidateState(1<<mActiveTrack); } - return NO_ERROR; } -status_t AudioMixer::setActiveTrack(int track) +void AudioMixer::setActiveTrack(int track) { - if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) { - return BAD_VALUE; - } - mActiveTrack = track - TRACK0; - return NO_ERROR; + // this also catches track < TRACK0 + track -= TRACK0; + assert(uint32_t(track) < MAX_NUM_TRACKS); + mActiveTrack = track; } -status_t AudioMixer::setParameter(int target, int name, void *value) +void AudioMixer::setParameter(int target, int name, void *value) { int valueInt = (int)value; int32_t *valueBuf = (int32_t *)value; switch (target) { + case TRACK: - if (name == CHANNEL_MASK) { + switch (name) { + case CHANNEL_MASK: { uint32_t mask = (uint32_t)value; if (mState.tracks[ mActiveTrack ].channelMask != mask) { uint8_t channelCount = popcount(mask); - if ((channelCount <= MAX_NUM_CHANNELS) && (channelCount)) { - mState.tracks[ mActiveTrack ].channelMask = mask; - mState.tracks[ mActiveTrack ].channelCount = channelCount; - ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask); - invalidateState(1<<mActiveTrack); - return NO_ERROR; - } - } else { - return NO_ERROR; + assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount)); + mState.tracks[ mActiveTrack ].channelMask = mask; + mState.tracks[ mActiveTrack ].channelCount = channelCount; + ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask); + invalidateState(1<<mActiveTrack); } - } - if (name == MAIN_BUFFER) { + } break; + case MAIN_BUFFER: if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) { mState.tracks[ mActiveTrack ].mainBuffer = valueBuf; ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf); invalidateState(1<<mActiveTrack); } - return NO_ERROR; - } - if (name == AUX_BUFFER) { + break; + case AUX_BUFFER: if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) { mState.tracks[ mActiveTrack ].auxBuffer = valueBuf; ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf); invalidateState(1<<mActiveTrack); } - return NO_ERROR; + break; + default: + // bad name + assert(false); } - break; + case RESAMPLE: - if (name == SAMPLE_RATE) { - if (valueInt > 0) { - track_t& track = mState.tracks[ mActiveTrack ]; - if (track.setResampler(uint32_t(valueInt), mSampleRate)) { - ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)", - uint32_t(valueInt)); - invalidateState(1<<mActiveTrack); - } - return NO_ERROR; + switch (name) { + case SAMPLE_RATE: { + assert(valueInt > 0); + track_t& track = mState.tracks[ mActiveTrack ]; + if (track.setResampler(uint32_t(valueInt), mSampleRate)) { + ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)", + uint32_t(valueInt)); + invalidateState(1<<mActiveTrack); } - } - if (name == RESET) { + } break; + case RESET: { track_t& track = mState.tracks[ mActiveTrack ]; track.resetResampler(); invalidateState(1<<mActiveTrack); - return NO_ERROR; + } break; + default: + // bad name + assert(false); } break; + case RAMP_VOLUME: case VOLUME: - if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) { + switch (name) { + case VOLUME0: + case VOLUME1: { track_t& track = mState.tracks[ mActiveTrack ]; if (track.volume[name-VOLUME0] != valueInt) { ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt); @@ -258,8 +250,8 @@ status_t AudioMixer::setParameter(int target, int name, void *value) } invalidateState(1<<mActiveTrack); } - return NO_ERROR; - } else if (name == AUXLEVEL) { + } break; + case AUXLEVEL: { track_t& track = mState.tracks[ mActiveTrack ]; if (track.auxLevel != valueInt) { ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt); @@ -278,11 +270,17 @@ status_t AudioMixer::setParameter(int target, int name, void *value) } invalidateState(1<<mActiveTrack); } - return NO_ERROR; + } break; + default: + // bad name + assert(false); } break; + + default: + // bad target + assert(false); } - return BAD_VALUE; } bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) @@ -290,7 +288,7 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) if (value!=devSampleRate || resampler) { if (sampleRate != value) { sampleRate = value; - if (resampler == 0) { + if (resampler == NULL) { resampler = AudioResampler::create( format, channelCount, devSampleRate); } @@ -302,12 +300,12 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) bool AudioMixer::track_t::doesResample() const { - return resampler != 0; + return resampler != NULL; } void AudioMixer::track_t::resetResampler() { - if (resampler != 0) { + if (resampler != NULL) { resampler->reset(); } } @@ -315,7 +313,7 @@ void AudioMixer::track_t::resetResampler() inline void AudioMixer::track_t::adjustVolumeRamp(bool aux) { - for (int i=0 ; i<2 ; i++) { + for (int i=0 ; i<MAX_NUM_CHANNELS ; i++) { if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) || ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) { volumeInc[i] = 0; @@ -332,10 +330,9 @@ void AudioMixer::track_t::adjustVolumeRamp(bool aux) } -status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer) +void AudioMixer::setBufferProvider(AudioBufferProvider* buffer) { mState.tracks[ mActiveTrack ].bufferProvider = buffer; - return NO_ERROR; } @@ -430,11 +427,11 @@ void AudioMixer::process__validate(state_t* state) } else { if (state->outputTemp) { delete [] state->outputTemp; - state->outputTemp = 0; + state->outputTemp = NULL; } if (state->resampleTemp) { delete [] state->resampleTemp; - state->resampleTemp = 0; + state->resampleTemp = NULL; } state->hook = process__genericNoResampling; if (all16BitsStereoNoResample && !volumeRamp) { @@ -450,115 +447,33 @@ void AudioMixer::process__validate(state_t* state) countActiveTracks, state->enabledTracks, all16BitsStereoNoResample, resampling, volumeRamp); - state->hook(state); - - // Now that the volume ramp has been done, set optimal state and - // track hooks for subsequent mixer process - if (countActiveTracks) { - int allMuted = 1; - uint32_t en = state->enabledTracks; - while (en) { - const int i = 31 - __builtin_clz(en); - en &= ~(1<<i); - track_t& t = state->tracks[i]; - if (!t.doesResample() && t.volumeRL == 0) - { - t.needs |= NEEDS_MUTE_ENABLED; - t.hook = track__nop; - } else { - allMuted = 0; - } - } - if (allMuted) { - state->hook = process__nop; - } else if (all16BitsStereoNoResample) { - if (countActiveTracks == 1) { - state->hook = process__OneTrack16BitsStereoNoResampling; - } - } - } -} - -static inline -int32_t mulAdd(int16_t in, int16_t v, int32_t a) -{ -#if defined(__arm__) && !defined(__thumb__) - int32_t out; - asm( "smlabb %[out], %[in], %[v], %[a] \n" - : [out]"=r"(out) - : [in]"%r"(in), [v]"r"(v), [a]"r"(a) - : ); - return out; -#else - return a + in * int32_t(v); -#endif -} - -static inline -int32_t mul(int16_t in, int16_t v) -{ -#if defined(__arm__) && !defined(__thumb__) - int32_t out; - asm( "smulbb %[out], %[in], %[v] \n" - : [out]"=r"(out) - : [in]"%r"(in), [v]"r"(v) - : ); - return out; -#else - return in * int32_t(v); -#endif -} + state->hook(state); -static inline -int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a) -{ -#if defined(__arm__) && !defined(__thumb__) - int32_t out; - if (left) { - asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n" - : [out]"=r"(out) - : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) - : ); - } else { - asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n" - : [out]"=r"(out) - : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) - : ); - } - return out; -#else - if (left) { - return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF); - } else { - return a + int16_t(inRL>>16) * int16_t(vRL>>16); - } -#endif -} - -static inline -int32_t mulRL(int left, uint32_t inRL, uint32_t vRL) -{ -#if defined(__arm__) && !defined(__thumb__) - int32_t out; - if (left) { - asm( "smulbb %[out], %[inRL], %[vRL] \n" - : [out]"=r"(out) - : [inRL]"%r"(inRL), [vRL]"r"(vRL) - : ); - } else { - asm( "smultt %[out], %[inRL], %[vRL] \n" - : [out]"=r"(out) - : [inRL]"%r"(inRL), [vRL]"r"(vRL) - : ); - } - return out; -#else - if (left) { - return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF); - } else { - return int16_t(inRL>>16) * int16_t(vRL>>16); + // Now that the volume ramp has been done, set optimal state and + // track hooks for subsequent mixer process + if (countActiveTracks) { + int allMuted = 1; + uint32_t en = state->enabledTracks; + while (en) { + const int i = 31 - __builtin_clz(en); + en &= ~(1<<i); + track_t& t = state->tracks[i]; + if (!t.doesResample() && t.volumeRL == 0) + { + t.needs |= NEEDS_MUTE_ENABLED; + t.hook = track__nop; + } else { + allMuted = 0; + } + } + if (allMuted) { + state->hook = process__nop; + } else if (all16BitsStereoNoResample) { + if (countActiveTracks == 1) { + state->hook = process__OneTrack16BitsStereoNoResampling; + } + } } -#endif } @@ -845,19 +760,6 @@ void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, t->in = in; } -void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c) -{ - for (size_t i=0 ; i<c ; i++) { - int32_t l = *sums++; - int32_t r = *sums++; - int32_t nl = l >> 12; - int32_t nr = r >> 12; - l = clamp16(nl); - r = clamp16(nr); - *out++ = (r<<16) | (l & 0xFFFF); - } -} - // no-op case void AudioMixer::process__nop(state_t* state) { @@ -993,7 +895,7 @@ void AudioMixer::process__genericNoResampling(state_t* state) } - // generic code with resampling +// generic code with resampling void AudioMixer::process__genericResampling(state_t* state) { int32_t* const outTemp = state->outputTemp; @@ -1174,7 +1076,7 @@ void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state) } in1 = buff; b1.frameCount = numFrames; - } else { + } else { in1 = b1.i16; } frameCount1 = b1.frameCount; diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h index f0bc9e8..70464fc 100644 --- a/services/audioflinger/AudioMixer.h +++ b/services/audioflinger/AudioMixer.h @@ -47,11 +47,10 @@ public: enum { // names - // track units (32 units) + // track units (MAX_NUM_TRACKS units) TRACK0 = 0x1000, - // enable/disable - MIXING = 0x2000, + // 0x2000 is unused // setParameter targets TRACK = 0x3000, @@ -65,10 +64,10 @@ public: FORMAT = 0x4001, MAIN_BUFFER = 0x4002, AUX_BUFFER = 0x4003, - // for TARGET RESAMPLE + // for target RESAMPLE SAMPLE_RATE = 0x4100, RESET = 0x4101, - // for TARGET VOLUME (8 channels max) + // for target RAMP_VOLUME and VOLUME (8 channels max) VOLUME0 = 0x4200, VOLUME1 = 0x4201, AUXLEVEL = 0x4210, @@ -78,19 +77,17 @@ public: int getTrackName(); void deleteTrackName(int name); - status_t enable(int name); - status_t disable(int name); + void enable(); + void disable(); - status_t setActiveTrack(int track); - status_t setParameter(int target, int name, void *value); + void setActiveTrack(int track); + void setParameter(int target, int name, void *value); - status_t setBufferProvider(AudioBufferProvider* bufferProvider); + void setBufferProvider(AudioBufferProvider* bufferProvider); void process(); uint32_t trackNames() const { return mTrackNames; } - static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c); - private: enum { @@ -128,13 +125,13 @@ private: uint32_t needs; union { - int16_t volume[2]; // [0]3.12 fixed point + int16_t volume[MAX_NUM_CHANNELS]; // [0]3.12 fixed point int32_t volumeRL; }; - int32_t prevVolume[2]; + int32_t prevVolume[MAX_NUM_CHANNELS]; - int32_t volumeInc[2]; + int32_t volumeInc[MAX_NUM_CHANNELS]; int32_t auxLevel; int32_t auxInc; int32_t prevAuxLevel; @@ -173,7 +170,7 @@ private: int32_t *outputTemp; int32_t *resampleTemp; int32_t reserved[2]; - track_t tracks[32]; __attribute__((aligned(32))); + track_t tracks[MAX_NUM_TRACKS]; __attribute__((aligned(32))); }; int mActiveTrack; diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 840d70d..bc4c90c 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -31,7 +31,6 @@ #include <utils/threads.h> #include "AudioPolicyService.h" #include <cutils/properties.h> -#include <dlfcn.h> #include <hardware_legacy/power.h> #include <media/AudioEffect.h> #include <media/EffectsFactoryApi.h> diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h index d898a53..88cb1e9 100644 --- a/services/audioflinger/AudioPolicyService.h +++ b/services/audioflinger/AudioPolicyService.h @@ -19,6 +19,7 @@ #include <cutils/misc.h> #include <cutils/config_utils.h> +#include <utils/String8.h> #include <utils/Vector.h> #include <utils/SortedVector.h> #include <binder/BinderService.h> @@ -31,8 +32,6 @@ namespace android { -class String8; - // ---------------------------------------------------------------------------- class AudioPolicyService : |