diff options
Diffstat (limited to 'services/audioflinger/AudioFlinger.cpp')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 634 |
1 files changed, 336 insertions, 298 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 5a46e44..f71ba0a 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -35,10 +35,10 @@ #include <cutils/bitops.h> #include <cutils/properties.h> +#include <cutils/compiler.h> -#include <media/AudioTrack.h> -#include <media/AudioRecord.h> #include <media/IMediaPlayerService.h> +#include <media/IMediaDeathNotifier.h> #include <private/media/AudioTrackShared.h> #include <private/media/AudioEffectShared.h> @@ -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,12 +65,12 @@ 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; -static const float MAX_GAIN_INT = 0x1000; +static const uint32_t MAX_GAIN_INT = 0x1000; // retry counts for buffer fill timeout // 50 * ~20msecs = 1 second @@ -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; @@ -113,11 +117,9 @@ static bool settingsAllowed() { // To collect the amplifier usage static void addBatteryData(uint32_t params) { - sp<IBinder> binder = - defaultServiceManager()->getService(String16("media.player")); - sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); - if (service.get() == NULL) { - ALOGW("Cannot connect to the MediaPlayerService for battery tracking"); + sp<IMediaPlayerService> service = IMediaDeathNotifier::getMediaPlayerService(); + if (service == NULL) { + // it already logged return; } @@ -147,7 +149,7 @@ out: return rc; } -static const char *audio_interfaces[] = { +static const char * const audio_interfaces[] = { "primary", "a2dp", "usb", @@ -158,7 +160,10 @@ static const char *audio_interfaces[] = { AudioFlinger::AudioFlinger() : BnAudioFlinger(), - mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), + mPrimaryHardwareDev(NULL), + mHardwareStatus(AUDIO_HW_IDLE), // see also onFirstRef() + mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), + mMode(AUDIO_MODE_INVALID), mBtNrecIsOff(false) { } @@ -170,7 +175,6 @@ void AudioFlinger::onFirstRef() Mutex::Autolock _l(mLock); /* TODO: move all this work into an Init() function */ - mHardwareStatus = AUDIO_HW_IDLE; for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) { const hw_module_t *mod; @@ -263,13 +267,10 @@ status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args) result.append("Clients:\n"); for (size_t i = 0; i < mClients.size(); ++i) { - wp<Client> wClient = mClients.valueAt(i); - if (wClient != 0) { - sp<Client> client = wClient.promote(); - if (client != 0) { - snprintf(buffer, SIZE, " pid: %d\n", client->pid()); - result.append(buffer); - } + sp<Client> client = mClients.valueAt(i).promote(); + if (client != 0) { + snprintf(buffer, SIZE, " pid: %d\n", client->pid()); + result.append(buffer); } } @@ -290,7 +291,7 @@ status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args) const size_t SIZE = 256; char buffer[SIZE]; String8 result; - int hardwareStatus = mHardwareStatus; + hardware_call_state hardwareStatus = mHardwareStatus; snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus); result.append(buffer); @@ -320,14 +321,14 @@ static bool tryLock(Mutex& mutex) locked = true; break; } - usleep(kDumpLockSleep); + usleep(kDumpLockSleepUs); } return locked; } status_t AudioFlinger::dump(int fd, const Vector<String16>& args) { - if (checkCallingPermission(String16("android.permission.DUMP")) == false) { + if (!checkCallingPermission(String16("android.permission.DUMP"))) { dumpPermissionDenial(fd, args); } else { // get state of hardware lock @@ -376,9 +377,9 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args) sp<IAudioTrack> AudioFlinger::createTrack( pid_t pid, - int streamType, + audio_stream_type_t streamType, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -394,8 +395,10 @@ sp<IAudioTrack> AudioFlinger::createTrack( status_t lStatus; int lSessionId; - if (streamType >= AUDIO_STREAM_CNT) { - ALOGE("invalid stream type"); + // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC, + // but if someone uses binder directly they could bypass that and cause us to crash + if (uint32_t(streamType) >= AUDIO_STREAM_CNT) { + ALOGE("createTrack() invalid stream type %d", streamType); lStatus = BAD_VALUE; goto Exit; } @@ -427,6 +430,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( // prevent same audio session on different output threads uint32_t sessions = t->hasAudioSession(*sessionId); if (sessions & PlaybackThread::TRACK_SESSION) { + ALOGE("createTrack() session ID %d already in use", *sessionId); lStatus = BAD_VALUE; goto Exit; } @@ -495,13 +499,13 @@ int AudioFlinger::channelCount(int output) const return thread->channelCount(); } -uint32_t AudioFlinger::format(int output) const +audio_format_t AudioFlinger::format(int output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); if (thread == NULL) { ALOGW("format() unknown thread %d", output); - return 0; + return AUDIO_FORMAT_INVALID; } return thread->format(); } @@ -558,7 +562,7 @@ status_t AudioFlinger::setMasterVolume(float value) return NO_ERROR; } -status_t AudioFlinger::setMode(int mode) +status_t AudioFlinger::setMode(audio_mode_t mode) { status_t ret = initCheck(); if (ret != NO_ERROR) { @@ -569,7 +573,7 @@ status_t AudioFlinger::setMode(int mode) if (!settingsAllowed()) { return PERMISSION_DENIED; } - if ((mode < 0) || (mode >= AUDIO_MODE_CNT)) { + if (uint32_t(mode) >= AUDIO_MODE_CNT) { ALOGW("Illegal value: setMode(%d)", mode); return BAD_VALUE; } @@ -641,22 +645,25 @@ status_t AudioFlinger::setMasterMute(bool muted) float AudioFlinger::masterVolume() const { - return mMasterVolume; + Mutex::Autolock _l(mLock); + return masterVolume_l(); } bool AudioFlinger::masterMute() const { - return mMasterMute; + Mutex::Autolock _l(mLock); + return masterMute_l(); } -status_t AudioFlinger::setStreamVolume(int stream, float value, int output) +status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, int output) { // check calling permissions if (!settingsAllowed()) { return PERMISSION_DENIED; } - if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) { + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + ALOGE("setStreamVolume() invalid stream %d", stream); return BAD_VALUE; } @@ -682,15 +689,16 @@ status_t AudioFlinger::setStreamVolume(int stream, float value, int output) return NO_ERROR; } -status_t AudioFlinger::setStreamMute(int stream, bool muted) +status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted) { // check calling permissions if (!settingsAllowed()) { return PERMISSION_DENIED; } - if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT || + if (uint32_t(stream) >= AUDIO_STREAM_CNT || uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) { + ALOGE("setStreamMute() invalid stream %d", stream); return BAD_VALUE; } @@ -702,9 +710,9 @@ status_t AudioFlinger::setStreamMute(int stream, bool muted) return NO_ERROR; } -float AudioFlinger::streamVolume(int stream, int output) const +float AudioFlinger::streamVolume(audio_stream_type_t stream, int output) const { - if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) { + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { return 0.0f; } @@ -723,9 +731,9 @@ float AudioFlinger::streamVolume(int stream, int output) const return volume; } -bool AudioFlinger::streamMute(int stream) const +bool AudioFlinger::streamMute(audio_stream_type_t stream) const { - if (stream < 0 || stream >= (int)AUDIO_STREAM_CNT) { + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { return true; } @@ -790,7 +798,7 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs) thread = checkPlaybackThread_l(ioHandle); if (thread == NULL) { thread = checkRecordThread_l(ioHandle); - } else if (thread.get() == primaryPlaybackThread_l()) { + } else if (thread == primaryPlaybackThread_l()) { // indicate output device change to all input threads for pre processing AudioParameter param = AudioParameter(keyValuePairs); int value; @@ -838,7 +846,7 @@ String8 AudioFlinger::getParameters(int ioHandle, const String8& keys) return String8(""); } -size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) +size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) { status_t ret = initCheck(); if (ret != NO_ERROR) { @@ -962,7 +970,8 @@ void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) { size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { - mNotificationClients.valueAt(i)->client()->ioConfigChanged(event, ioHandle, param2); + mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioHandle, + param2); } } @@ -976,19 +985,24 @@ void AudioFlinger::removeClient_l(pid_t pid) // ---------------------------------------------------------------------------- -AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device) +AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device, + type_t type) : Thread(false), - mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0), - mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), - mDevice(device) + mType(type), + mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), + // mChannelMask + mChannelCount(0), + mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID), + mParamStatus(NO_ERROR), + mStandby(false), mId(id), mExiting(false), + mDevice(device), + mDeathRecipient(new PMDeathRecipient(this)) { - mDeathRecipient = new PMDeathRecipient(this); } AudioFlinger::ThreadBase::~ThreadBase() { mParamCond.broadcast(); - mNewParameters.clear(); // do not lock the mutex in destructor releaseWakeLock_l(); if (mPowerManager != 0) { @@ -999,13 +1013,13 @@ 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; ALOGV("ThreadBase::exit"); { - AutoMutex lock(&mLock); + AutoMutex lock(mLock); mExiting = true; requestExit(); mWaitWorkCV.signal(); @@ -1023,7 +1037,7 @@ int AudioFlinger::ThreadBase::channelCount() const return (int)mChannelCount; } -uint32_t AudioFlinger::ThreadBase::format() const +audio_format_t AudioFlinger::ThreadBase::format() const { return mFormat; } @@ -1044,7 +1058,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 +1076,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 +1089,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(); @@ -1113,7 +1126,7 @@ status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args result.append(buffer); snprintf(buffer, SIZE, "Format: %d\n", mFormat); result.append(buffer); - snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize); + snprintf(buffer, SIZE, "Frame size: %u\n", mFrameSize); result.append(buffer); snprintf(buffer, SIZE, "\nPending setParameters commands: \n"); @@ -1130,7 +1143,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"); @@ -1365,22 +1378,32 @@ void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModu AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, - uint32_t device) - : ThreadBase(audioFlinger, id, device), - mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output), + uint32_t device, + type_t type) + : ThreadBase(audioFlinger, id, device, type), + mMixBuffer(NULL), mSuspended(0), mBytesWritten(0), + // Assumes constructor is called by AudioFlinger with it's mLock held, + // but it would be safer to explicitly pass initial masterMute as parameter + mMasterMute(audioFlinger->masterMute_l()), + // mStreamTypes[] initialized in constructor body + mOutput(output), + // Assumes constructor is called by AudioFlinger with it's mLock held, + // but it would be safer to explicitly pass initial masterVolume as parameter + mMasterVolume(audioFlinger->masterVolume_l()), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false) { snprintf(mName, kNameLength, "AudioOut_%d", id); readOutputParameters(); - mMasterVolume = mAudioFlinger->masterVolume(); - mMasterMute = mAudioFlinger->masterMute(); - - for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { + // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor + // There is no AUDIO_STREAM_MIN, and ++ operator does not compile + for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT; + stream = (audio_stream_type_t) (stream + 1)) { mStreamTypes[stream].volume = mAudioFlinger->streamVolumeInternal(stream); mStreamTypes[stream].mute = mAudioFlinger->streamMute(stream); - mStreamTypes[stream].valid = true; + // initialized by stream_type_t default constructor + // mStreamTypes[stream].valid = true; } } @@ -1418,13 +1441,10 @@ status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16> result.append(buffer); result.append(" Name Clien Typ Fmt Chn mask Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n"); for (size_t i = 0; i < mActiveTracks.size(); ++i) { - wp<Track> wTrack = mActiveTracks[i]; - if (wTrack != 0) { - sp<Track> track = wTrack.promote(); - if (track != 0) { - track->dump(buffer, SIZE); - result.append(buffer); - } + sp<Track> track = mActiveTracks[i].promote(); + if (track != 0) { + track->dump(buffer, SIZE); + result.append(buffer); } } write(fd, result.string(), result.size()); @@ -1478,9 +1498,9 @@ void AudioFlinger::PlaybackThread::onFirstRef() // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l( const sp<AudioFlinger::Client>& client, - int streamType, + audio_stream_type_t streamType, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, const sp<IMemory>& sharedBuffer, @@ -1526,8 +1546,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) { + ALOGE("createTrack_l() mismatched strategy; expected %u but found %u", + strategy, actual); lStatus = BAD_VALUE; goto Exit; } @@ -1599,24 +1621,24 @@ bool AudioFlinger::PlaybackThread::masterMute() const return mMasterMute; } -status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value) +status_t AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) { mStreamTypes[stream].volume = value; return NO_ERROR; } -status_t AudioFlinger::PlaybackThread::setStreamMute(int stream, bool muted) +status_t AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) { mStreamTypes[stream].mute = muted; return NO_ERROR; } -float AudioFlinger::PlaybackThread::streamVolume(int stream) const +float AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; } -bool AudioFlinger::PlaybackThread::streamMute(int stream) const +bool AudioFlinger::PlaybackThread::streamMute(audio_stream_type_t stream) const { return mStreamTypes[stream].mute; } @@ -1690,7 +1712,7 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) // audioConfigChanged_l() must be called with AudioFlinger::mLock held void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) { AudioSystem::OutputDescriptor desc; - void *param2 = 0; + void *param2 = NULL; ALOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event, param); @@ -1720,12 +1742,12 @@ void AudioFlinger::PlaybackThread::readOutputParameters() mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common); mChannelCount = (uint16_t)popcount(mChannelMask); mFormat = mOutput->stream->common.get_format(&mOutput->stream->common); - mFrameSize = (uint16_t)audio_stream_frame_size(&mOutput->stream->common); + mFrameSize = audio_stream_frame_size(&mOutput->stream->common); mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize; // FIXME - Current mixer implementation only supports stereo output: Always // Allocate a stereo buffer even if HW output is mono. - if (mMixBuffer != NULL) delete[] mMixBuffer; + delete[] mMixBuffer; mMixBuffer = new int16_t[mFrameCount * 2]; memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t)); @@ -1743,7 +1765,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters() status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames) { - if (halFrames == 0 || dspFrames == 0) { + if (halFrames == NULL || dspFrames == NULL) { return BAD_VALUE; } Mutex::Autolock _l(mLock); @@ -1793,7 +1815,7 @@ uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId) } -AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput() +AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const { Mutex::Autolock _l(mLock); return mOutput; @@ -1830,13 +1852,12 @@ 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), mPrevMixerStatus(MIXER_IDLE) +AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, + int id, uint32_t device, type_t type) + : PlaybackThread(audioFlinger, output, id, device, type), + mAudioMixer(new AudioMixer(mFrameCount, mSampleRate)), + mPrevMixerStatus(MIXER_IDLE) { - mType = ThreadBase::MIXER; - mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); - // FIXME - Current mixer implementation only supports stereo output if (mChannelCount == 1) { ALOGE("Invalid audio hardware channel count"); @@ -1851,7 +1872,7 @@ AudioFlinger::MixerThread::~MixerThread() bool AudioFlinger::MixerThread::threadLoop() { Vector< sp<Track> > tracksToRemove; - uint32_t mixerStatus = MIXER_IDLE; + mixer_state mixerStatus = MIXER_IDLE; nsecs_t standbyTime = systemTime(); size_t mixBufferSize = mFrameCount * mFrameSize; // FIXME: Relaxed timing because of a certain device that can't meet latency @@ -1923,8 +1944,8 @@ bool AudioFlinger::MixerThread::threadLoop() const SortedVector< wp<Track> >& activeTracks = mActiveTracks; // put audio hardware into standby after short delay - if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) || - mSuspended) { + if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) || + mSuspended)) { if (!mStandby) { ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d\n", this, mSuspended); mOutput->stream->common.standby(&mOutput->stream->common); @@ -1946,7 +1967,7 @@ bool AudioFlinger::MixerThread::threadLoop() acquireWakeLock_l(); mPrevMixerStatus = MIXER_IDLE; - if (mMasterMute == false) { + if (!mMasterMute) { char value[PROPERTY_VALUE_MAX]; property_get("ro.audio.silent", value, "0"); if (atoi(value)) { @@ -1968,9 +1989,9 @@ 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)) { + if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) { // mix buffers... mAudioMixer->process(); // increase sleep time progressively when application underrun condition clears. @@ -2016,11 +2037,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; @@ -2033,7 +2054,7 @@ bool AudioFlinger::MixerThread::threadLoop() nsecs_t delta = now - mLastWriteTime; if (!mStandby && delta > maxPeriod) { mNumDelayedWrites++; - if ((now - lastWarning) > kWarningThrottle) { + if ((now - lastWarning) > kWarningThrottleNs) { ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p", ns2ms(delta), mNumDelayedWrites, this); lastWarning = now; @@ -2070,10 +2091,11 @@ bool AudioFlinger::MixerThread::threadLoop() } // prepareTracks_l() must be called with ThreadBase::mLock held -uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove) +AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l( + const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove) { - uint32_t mixerStatus = MIXER_IDLE; + mixer_state mixerStatus = MIXER_IDLE; // find out which tracks need to be processed size_t count = activeTracks.size(); size_t mixedTracks = 0; @@ -2098,12 +2120,13 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track sp<Track> t = activeTracks[i].promote(); if (t == 0) continue; + // this const just means the local variable doesn't change Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); // The first time a track is added we wait // for all its buffers to be filled before processing it - mAudioMixer->setActiveTrack(track->name()); + int name = track->name(); // make sure that we have enough frames to mix one full buffer. // enforce this condition only once to enable draining the buffer in case the client // app does not call stop() and relies on underrun to stop: @@ -2123,13 +2146,13 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track // the minimum track buffer size is normally twice the number of frames necessary // to fill one buffer and the resampler should not leave more than one buffer worth // of unreleased frames after each pass, but just in case... - LOG_ASSERT(minFrames <= cblk->frameCount); + ALOG_ASSERT(minFrames <= cblk->frameCount); } } if ((cblk->framesReady() >= minFrames) && track->isReady() && !track->isPaused() && !track->isTerminated()) { - //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this); + //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server, this); mixedTracks++; @@ -2142,8 +2165,8 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track if (chain != 0) { tracksWithEffect++; } else { - ALOGW("prepareTracks_l(): track %08x attached to effect but no chain found on session %d", - track->name(), track->sessionId()); + ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on session %d", + name, track->sessionId()); } } @@ -2156,7 +2179,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track track->mState = TrackBase::ACTIVE; param = AudioMixer::RAMP_VOLUME; } - mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::RESET, NULL); + mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL); } else if (cblk->server != 0) { // If the track is stopped before the first frame was mixed, // do not apply ramp @@ -2176,10 +2199,31 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track // read original volumes with volume control float typeVolume = mStreamTypes[track->type()].volume; float v = masterVolume * typeVolume; - vl = (uint32_t)(v * cblk->volume[0]) << 12; - vr = (uint32_t)(v * cblk->volume[1]) << 12; - - va = (uint32_t)(v * cblk->sendLevel); + uint32_t vlr = cblk->getVolumeLR(); + vl = vlr & 0xFFFF; + vr = vlr >> 16; + // track volumes come from shared memory, so can't be trusted and must be clamped + if (vl > MAX_GAIN_INT) { + ALOGV("Track left volume out of range: %04X", vl); + vl = MAX_GAIN_INT; + } + if (vr > MAX_GAIN_INT) { + ALOGV("Track right volume out of range: %04X", vr); + vr = MAX_GAIN_INT; + } + // now apply the master volume and stream type volume + vl = (uint32_t)(v * vl) << 12; + vr = (uint32_t)(v * vr) << 12; + // assuming master volume and stream type volume each go up to 1.0, + // vl and vr are now in 8.24 format + + uint16_t sendLevel = cblk->getSendLevel_U4_12(); + // send level comes from shared memory and so may be corrupt + if (sendLevel >= MAX_GAIN_INT) { + ALOGV("Track send level out of range: %04X", sendLevel); + sendLevel = MAX_GAIN_INT; + } + va = (uint32_t)(v * sendLevel); } // Delegate volume control to effect in track effect chain if needed if (chain != 0 && chain->setVolume_l(&vl, &vr)) { @@ -2197,6 +2241,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track // Convert volumes from 8.24 to 4.12 format int16_t left, right, aux; + // This additional clamping is needed in case chain->setVolume_l() overshot uint32_t v_clamped = (vl + (1 << 11)) >> 12; if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT; left = int16_t(v_clamped); @@ -2208,26 +2253,31 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track aux = int16_t(va); // XXX: these things DON'T need to be done each time - mAudioMixer->setBufferProvider(track); - mAudioMixer->enable(AudioMixer::MIXING); + mAudioMixer->setBufferProvider(name, track); + mAudioMixer->enable(name); - mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left); - mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right); - mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux); + mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)left); + mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)right); + mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)aux); mAudioMixer->setParameter( + name, AudioMixer::TRACK, AudioMixer::FORMAT, (void *)track->format()); mAudioMixer->setParameter( + name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *)track->channelMask()); mAudioMixer->setParameter( + name, AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE, (void *)(cblk->sampleRate)); mAudioMixer->setParameter( + name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer()); mAudioMixer->setParameter( + name, AudioMixer::TRACK, AudioMixer::AUX_BUFFER, (void *)track->auxBuffer()); @@ -2241,7 +2291,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track mixerStatus = MIXER_TRACKS_READY; } } else { - //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this); + //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user, cblk->server, this); if (track->isStopped()) { track->reset(); } @@ -2253,7 +2303,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track // No buffers for this track. Give it a few chances to // fill a buffer, then remove it from active list. if (--(track->mRetryCount) <= 0) { - ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this); + ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this); tracksToRemove->add(track); // indicate to client process that the track was disabled because of underrun android_atomic_or(CBLK_DISABLED_ON, &cblk->flags); @@ -2265,13 +2315,13 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track mixerStatus = MIXER_TRACKS_ENABLED; } } - mAudioMixer->disable(AudioMixer::MIXING); + mAudioMixer->disable(name); } } // remove all the tracks that need to be... count = tracksToRemove->size(); - if (UNLIKELY(count)) { + if (CC_UNLIKELY(count)) { for (size_t i=0 ; i<count ; i++) { const sp<Track>& track = tracksToRemove->itemAt(i); mActiveTracks.remove(track); @@ -2299,7 +2349,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track return mixerStatus; } -void AudioFlinger::MixerThread::invalidateTracks(int streamType) +void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType) { ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d", this, streamType, mTracks.size()); @@ -2315,7 +2365,7 @@ void AudioFlinger::MixerThread::invalidateTracks(int streamType) } } -void AudioFlinger::PlaybackThread::setStreamValid(int streamType, bool valid) +void AudioFlinger::PlaybackThread::setStreamValid(audio_stream_type_t streamType, bool valid) { ALOGV ("PlaybackThread::setStreamValid() thread %p, streamType %d, valid %d", this, streamType, valid); @@ -2352,7 +2402,7 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() reconfig = true; } if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) { - if (value != AUDIO_FORMAT_PCM_16_BIT) { + if ((audio_format_t) value != AUDIO_FORMAT_PCM_16_BIT) { status = BAD_VALUE; } else { reconfig = true; @@ -2367,7 +2417,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; @@ -2417,6 +2467,8 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() } if (status == NO_ERROR && reconfig) { delete mAudioMixer; + // for safety in case readOutputParameters() accesses mAudioMixer (it doesn't) + mAudioMixer = NULL; readOutputParameters(); mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); for (size_t i = 0; i < mTracks.size() ; i++) { @@ -2438,7 +2490,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; } @@ -2469,23 +2521,16 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() // ---------------------------------------------------------------------------- AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device) - : PlaybackThread(audioFlinger, output, id, device) + : PlaybackThread(audioFlinger, output, id, device, DIRECT) + // mLeftVolFloat, mRightVolFloat + // mLeftVolShort, mRightVolShort { - mType = ThreadBase::DIRECT; } 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) { @@ -2577,7 +2622,7 @@ void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t ri bool AudioFlinger::DirectOutputThread::threadLoop() { - uint32_t mixerStatus = MIXER_IDLE; + mixer_state mixerStatus = MIXER_IDLE; sp<Track> trackToRemove; sp<Track> activeTrack; nsecs_t standbyTime = systemTime(); @@ -2615,8 +2660,8 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } // put audio hardware into standby after short delay - if UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) || - mSuspended) { + if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) || + mSuspended)) { // wait until we have something to do... if (!mStandby) { ALOGV("Audio hardware entering standby, mixer %p\n", this); @@ -2637,7 +2682,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() ALOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid()); acquireWakeLock_l(); - if (mMasterMute == false) { + if (!mMasterMute) { char value[PROPERTY_VALUE_MAX]; property_get("ro.audio.silent", value, "0"); if (atoi(value)) { @@ -2693,10 +2738,11 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } else { float typeVolume = mStreamTypes[track->type()].volume; float v = mMasterVolume * typeVolume; - float v_clamped = v * cblk->volume[0]; + uint32_t vlr = cblk->getVolumeLR(); + float v_clamped = v * (vlr & 0xFFFF); if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN; left = v_clamped/MAX_GAIN; - v_clamped = v * cblk->volume[1]; + v_clamped = v * (vlr >> 16); if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN; right = v_clamped/MAX_GAIN; } @@ -2766,7 +2812,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } // remove all the tracks that need to be... - if (UNLIKELY(trackToRemove != 0)) { + if (CC_UNLIKELY(trackToRemove != 0)) { mActiveTracks.remove(trackToRemove); if (!effectChains.isEmpty()) { ALOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(), @@ -2781,7 +2827,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() lockEffectChains_l(effectChains); } - if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { + if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) { AudioBufferProvider::Buffer buffer; size_t frameCount = mFrameCount; curBuf = (int8_t *)mMixBuffer; @@ -2789,7 +2835,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() while (frameCount) { buffer.frameCount = frameCount; activeTrack->getNextBuffer(&buffer); - if (UNLIKELY(buffer.raw == 0)) { + if (CC_UNLIKELY(buffer.raw == NULL)) { memset(curBuf, 0, frameCount * mFrameSize); break; } @@ -2914,7 +2960,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; } @@ -2955,10 +3001,11 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() // ---------------------------------------------------------------------------- -AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id) - : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device()), mWaitTimeMs(UINT_MAX) +AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, + AudioFlinger::MixerThread* mainThread, int id) + : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device(), DUPLICATING), + mWaitTimeMs(UINT_MAX) { - mType = ThreadBase::DUPLICATING; addOutputTrack(mainThread); } @@ -2973,7 +3020,7 @@ AudioFlinger::DuplicatingThread::~DuplicatingThread() bool AudioFlinger::DuplicatingThread::threadLoop() { Vector< sp<Track> > tracksToRemove; - uint32_t mixerStatus = MIXER_IDLE; + mixer_state mixerStatus = MIXER_IDLE; nsecs_t standbyTime = systemTime(); size_t mixBufferSize = mFrameCount*mFrameSize; SortedVector< sp<OutputTrack> > outputTracks; @@ -3008,8 +3055,8 @@ bool AudioFlinger::DuplicatingThread::threadLoop() } // put audio hardware into standby after short delay - if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) || - mSuspended) { + if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) || + mSuspended)) { if (!mStandby) { for (size_t i = 0; i < outputTracks.size(); i++) { outputTracks[i]->stop(); @@ -3032,7 +3079,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop() acquireWakeLock_l(); mPrevMixerStatus = MIXER_IDLE; - if (mMasterMute == false) { + if (!mMasterMute) { char value[PROPERTY_VALUE_MAX]; property_get("ro.audio.silent", value, "0"); if (atoi(value)) { @@ -3055,7 +3102,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop() lockEffectChains_l(effectChains); } - if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { + if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) { // mix buffers... if (outputsReady(outputTracks)) { mAudioMixer->process(); @@ -3198,7 +3245,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -3207,13 +3254,17 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( : RefBase(), mThread(thread), mClient(client), - mCblk(0), + mCblk(NULL), + // mBuffer + // mBufferEnd mFrameCount(0), mState(IDLE), mClientTid(-1), mFormat(format), mFlags(flags & ~SYSTEM_FLAGS_MASK), mSessionId(sessionId) + // mChannelCount + // mChannelMask { ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); @@ -3229,7 +3280,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( mCblkMemory = client->heap()->allocate(size); if (mCblkMemory != 0) { mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer()); - if (mCblk) { // construct the shared structure in-place. + if (mCblk != NULL) { // construct the shared structure in-place. new(mCblk) audio_track_cblk_t(); // clear all buffers mCblk->frameCount = frameCount; @@ -3254,7 +3305,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( } } else { mCblk = (audio_track_cblk_t *)(new uint8_t[size]); - if (mCblk) { // construct the shared structure in-place. + // construct the shared structure in-place. new(mCblk) audio_track_cblk_t(); // clear all buffers mCblk->frameCount = frameCount; @@ -3267,13 +3318,12 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // written to buffer (other flags are cleared) mCblk->flags = CBLK_UNDERRUN_ON; mBufferEnd = (uint8_t *)mBuffer + bufferSize; - } } } AudioFlinger::ThreadBase::TrackBase::~TrackBase() { - if (mCblk) { + if (mCblk != NULL) { mCblk->~audio_track_cblk_t(); // destroy our shared-structure. if (mClient == NULL) { delete mCblk; @@ -3281,6 +3331,7 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase() } mCblkMemory.clear(); // and free the shared memory if (mClient != NULL) { + // Client destructor must run with AudioFlinger mutex locked Mutex::Autolock _l(mClient->audioFlinger()->mLock); mClient.clear(); } @@ -3288,7 +3339,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; @@ -3336,17 +3387,18 @@ uint32_t AudioFlinger::ThreadBase::TrackBase::channelMask() const { void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const { audio_track_cblk_t* cblk = this->cblk(); - int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*cblk->frameSize; - int8_t *bufferEnd = bufferStart + frames * cblk->frameSize; + size_t frameSize = cblk->frameSize; + int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*frameSize; + int8_t *bufferEnd = bufferStart + frames * frameSize; // Check validity of returned pointer in case the track control block would have been corrupted. if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd || - ((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) { + ((unsigned long)bufferStart & (unsigned long)(frameSize - 1))) { ALOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \ server %d, serverBase %d, user %d, userBase %d", bufferStart, bufferEnd, mBuffer, mBufferEnd, cblk->server, cblk->serverBase, cblk->user, cblk->userBase); - return 0; + return NULL; } return bufferStart; @@ -3358,9 +3410,9 @@ void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t f AudioFlinger::PlaybackThread::Track::Track( const wp<ThreadBase>& thread, const sp<Client>& client, - int streamType, + audio_stream_type_t streamType, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, const sp<IMemory>& sharedBuffer, @@ -3380,8 +3432,6 @@ AudioFlinger::PlaybackThread::Track::Track( if (mName < 0) { ALOGE("no more track names available"); } - mVolume[0] = 1.0f; - mVolume[1] = 1.0f; mStreamType = streamType; // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack @@ -3433,6 +3483,7 @@ void AudioFlinger::PlaybackThread::Track::destroy() void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) { + uint32_t vlr = mCblk->getVolumeLR(); snprintf(buffer, size, " %05d %05d %03u %03u 0x%08x %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n", mName - AudioMixer::TRACK0, (mClient == NULL) ? getpid() : mClient->pid(), @@ -3445,8 +3496,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) mMute, mFillingUpStatus, mCblk->sampleRate, - mCblk->volume[0], - mCblk->volume[1], + vlr & 0xFFFF, + vlr >> 16, mCblk->server, mCblk->user, (int)mMainBuffer, @@ -3468,7 +3519,7 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider: framesReady = cblk->framesReady(); - if (LIKELY(framesReady)) { + if (CC_LIKELY(framesReady)) { uint32_t s = cblk->server; uint32_t bufferEnd = cblk->serverBase + cblk->frameCount; @@ -3481,14 +3532,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; @@ -3514,7 +3565,7 @@ status_t AudioFlinger::PlaybackThread::Track::start() sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - int state = mState; + track_state state = mState; // here the track could be either new, or restarted // in both cases "unstop" the track if (mState == PAUSED) { @@ -3555,7 +3606,7 @@ void AudioFlinger::PlaybackThread::Track::stop() sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - int state = mState; + track_state state = mState; if (mState > STOPPED) { mState = STOPPED; // If the track is not active (PAUSED and buffers full), flush buffers @@ -3643,12 +3694,6 @@ void AudioFlinger::PlaybackThread::Track::mute(bool muted) mMute = muted; } -void AudioFlinger::PlaybackThread::Track::setVolume(float left, float right) -{ - mVolume[0] = left; - mVolume[1] = right; -} - status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId) { status_t status = DEAD_OBJECT; @@ -3673,7 +3718,7 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -3717,7 +3762,7 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi framesAvail = cblk->framesAvailable_l(); - if (LIKELY(framesAvail)) { + if (CC_LIKELY(framesAvail)) { uint32_t s = cblk->server; uint32_t bufferEnd = cblk->serverBase + cblk->frameCount; @@ -3729,14 +3774,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; } @@ -3786,7 +3831,7 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( const wp<ThreadBase>& thread, DuplicatingThread *sourceThread, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount) : Track(thread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, NULL, 0), @@ -3797,7 +3842,6 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( if (mCblk != NULL) { mCblk->flags |= CBLK_DIRECTION_OUT; mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); - mCblk->volume[0] = mCblk->volume[1] = 0x1000; mOutBuffer.frameCount = 0; playbackThread->mTracks.add(this); ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \ @@ -3881,7 +3925,7 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr if (mOutBuffer.frameCount == 0) { mOutBuffer.frameCount = pInBuffer->frameCount; nsecs_t startTime = systemTime(); - if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)AudioTrack::NO_MORE_BUFFERS) { + if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)NO_MORE_BUFFERS) { ALOGV ("OutputTrack::write() %p thread %p no more output buffers", this, mThread.unsafe_get()); outputBufferFull = true; break; @@ -3970,13 +4014,13 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProv goto start_loop_here; while (framesAvail == 0) { active = mActive; - if (UNLIKELY(!active)) { + if (CC_UNLIKELY(!active)) { ALOGV("Not active and NO_MORE_BUFFERS"); - return AudioTrack::NO_MORE_BUFFERS; + return NO_MORE_BUFFERS; } result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); if (result != NO_ERROR) { - return AudioTrack::NO_MORE_BUFFERS; + return NO_MORE_BUFFERS; } // read the server count again start_loop_here: @@ -3985,7 +4029,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProv } // if (framesAvail < framesReq) { -// return AudioTrack::NO_MORE_BUFFERS; +// return NO_MORE_BUFFERS; // } if (framesReq > framesAvail) { @@ -4035,7 +4079,7 @@ AudioFlinger::Client::~Client() mAudioFlinger->removeClient_l(mPid); } -const sp<MemoryDealer>& AudioFlinger::Client::heap() const +sp<MemoryDealer> AudioFlinger::Client::heap() const { return mMemoryDealer; } @@ -4045,13 +4089,12 @@ const sp<MemoryDealer>& AudioFlinger::Client::heap() const AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger, const sp<IAudioFlingerClient>& client, pid_t pid) - : mAudioFlinger(audioFlinger), mPid(pid), mClient(client) + : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client) { } AudioFlinger::NotificationClient::~NotificationClient() { - mClient.clear(); } void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who) @@ -4078,6 +4121,10 @@ AudioFlinger::TrackHandle::~TrackHandle() { mTrack->destroy(); } +sp<IMemory> AudioFlinger::TrackHandle::getCblk() const { + return mTrack->getCblk(); +} + status_t AudioFlinger::TrackHandle::start() { return mTrack->start(); } @@ -4098,14 +4145,6 @@ void AudioFlinger::TrackHandle::pause() { mTrack->pause(); } -void AudioFlinger::TrackHandle::setVolume(float left, float right) { - mTrack->setVolume(left, right); -} - -sp<IMemory> AudioFlinger::TrackHandle::getCblk() const { - return mTrack->getCblk(); -} - status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId) { return mTrack->attachAuxEffect(EffectId); @@ -4123,7 +4162,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( pid_t pid, int input, uint32_t sampleRate, - uint32_t format, + audio_format_t format, uint32_t channelMask, int frameCount, uint32_t flags, @@ -4212,6 +4251,10 @@ AudioFlinger::RecordHandle::~RecordHandle() { stop(); } +sp<IMemory> AudioFlinger::RecordHandle::getCblk() const { + return mRecordTrack->getCblk(); +} + status_t AudioFlinger::RecordHandle::start() { ALOGV("RecordHandle::start()"); return mRecordTrack->start(); @@ -4222,10 +4265,6 @@ void AudioFlinger::RecordHandle::stop() { mRecordTrack->stop(); } -sp<IMemory> AudioFlinger::RecordHandle::getCblk() const { - return mRecordTrack->getCblk(); -} - status_t AudioFlinger::RecordHandle::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { @@ -4240,15 +4279,16 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, uint32_t channels, int id, uint32_t device) : - ThreadBase(audioFlinger, id, device), - mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0) + ThreadBase(audioFlinger, id, device, RECORD), + mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL), + // mRsmpInIndex and mInputBytes set by readInputParameters() + mReqChannelCount(popcount(channels)), + mReqSampleRate(sampleRate) + // mBytesRead is only meaningful while active, and so is cleared in start() + // (but might be better to also clear here for dump?) { - mType = ThreadBase::RECORD; - snprintf(mName, kNameLength, "AudioIn_%d", id); - mReqChannelCount = popcount(channels); - mReqSampleRate = sampleRate; readInputParameters(); } @@ -4256,10 +4296,8 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::RecordThread::~RecordThread() { delete[] mRsmpInBuffer; - if (mResampler != 0) { - delete mResampler; - delete[] mRsmpOutBuffer; - } + delete mResampler; + delete[] mRsmpOutBuffer; } void AudioFlinger::RecordThread::onFirstRef() @@ -4348,9 +4386,9 @@ bool AudioFlinger::RecordThread::threadLoop() } buffer.frameCount = mFrameCount; - if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) { + if (CC_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; @@ -4415,7 +4453,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; @@ -4424,7 +4462,7 @@ bool AudioFlinger::RecordThread::threadLoop() src += 2; } } else { - AudioMixer::ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut); + ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut); } } @@ -4435,7 +4473,7 @@ bool AudioFlinger::RecordThread::threadLoop() else { if (!mActiveTrack->setOverflow()) { nsecs_t now = systemTime(); - if ((now - lastWarning) > kWarningThrottle) { + if ((now - lastWarning) > kWarningThrottleNs) { ALOGW("RecordThread: buffer overflow"); lastWarning = now; } @@ -4468,7 +4506,7 @@ bool AudioFlinger::RecordThread::threadLoop() sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l( const sp<AudioFlinger::Client>& client, uint32_t sampleRate, - int format, + audio_format_t format, int channelMask, int frameCount, uint32_t flags, @@ -4517,7 +4555,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac sp <ThreadBase> strongMe = this; status_t status = NO_ERROR; { - AutoMutex lock(&mLock); + AutoMutex lock(mLock); if (mActiveTrack != 0) { if (recordTrack != mActiveTrack.get()) { status = -EBUSY; @@ -4569,7 +4607,7 @@ void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) { ALOGV("RecordThread::stop"); sp <ThreadBase> strongMe = this; { - AutoMutex lock(&mLock); + AutoMutex lock(mLock); if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) { mActiveTrack->mState = TrackBase::PAUSING; // do not wait for mStartStopCond if exiting @@ -4608,7 +4646,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); @@ -4643,7 +4681,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; } @@ -4680,7 +4718,7 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l() String8 keyValuePair = mNewParameters[0]; AudioParameter param = AudioParameter(keyValuePair); int value; - int reqFormat = mFormat; + audio_format_t reqFormat = mFormat; int reqSamplingRate = mReqSampleRate; int reqChannelCount = mReqChannelCount; @@ -4689,7 +4727,7 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l() reconfig = true; } if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) { - reqFormat = value; + reqFormat = (audio_format_t) value; reconfig = true; } if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) { @@ -4758,7 +4796,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; } @@ -4781,7 +4819,7 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys) void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) { AudioSystem::OutputDescriptor desc; - void *param2 = 0; + void *param2 = NULL; switch (event) { case AudioSystem::INPUT_OPENED: @@ -4803,16 +4841,18 @@ void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) { void AudioFlinger::RecordThread::readInputParameters() { - if (mRsmpInBuffer) delete mRsmpInBuffer; - if (mRsmpOutBuffer) delete mRsmpOutBuffer; - if (mResampler) delete mResampler; - mResampler = 0; + delete mRsmpInBuffer; + // mRsmpInBuffer is always assigned a new[] below + delete mRsmpOutBuffer; + mRsmpOutBuffer = NULL; + delete mResampler; + mResampler = NULL; mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common); mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common); mChannelCount = (uint16_t)popcount(mChannelMask); mFormat = mInput->stream->common.get_format(&mInput->stream->common); - mFrameSize = (uint16_t)audio_stream_frame_size(&mInput->stream->common); + mFrameSize = audio_stream_frame_size(&mInput->stream->common); mInputBytes = mInput->stream->common.get_buffer_size(&mInput->stream->common); mFrameCount = mInputBytes / mFrameSize; mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount]; @@ -4872,7 +4912,7 @@ AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track() return mTrack; } -AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::getInput() +AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::getInput() const { Mutex::Autolock _l(mLock); return mInput; @@ -4900,7 +4940,7 @@ audio_stream_t* AudioFlinger::RecordThread::stream() int AudioFlinger::openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, - uint32_t *pFormat, + audio_format_t *pFormat, uint32_t *pChannels, uint32_t *pLatencyMs, uint32_t flags) @@ -4909,7 +4949,7 @@ int AudioFlinger::openOutput(uint32_t *pDevices, PlaybackThread *thread = NULL; mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; - uint32_t format = pFormat ? *pFormat : 0; + audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; uint32_t channels = pChannels ? *pChannels : 0; uint32_t latency = pLatencyMs ? *pLatencyMs : 0; audio_stream_out_t *outStream; @@ -4932,7 +4972,7 @@ int AudioFlinger::openOutput(uint32_t *pDevices, if (outHwDev == NULL) return 0; - status = outHwDev->open_output_stream(outHwDev, *pDevices, (int *)&format, + status = outHwDev->open_output_stream(outHwDev, *pDevices, &format, &channels, &samplingRate, &outStream); ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d", outStream, @@ -4957,10 +4997,10 @@ int AudioFlinger::openOutput(uint32_t *pDevices, } mPlaybackThreads.add(id, thread); - if (pSamplingRate) *pSamplingRate = samplingRate; - if (pFormat) *pFormat = format; - if (pChannels) *pChannels = channels; - if (pLatencyMs) *pLatencyMs = thread->latency(); + if (pSamplingRate != NULL) *pSamplingRate = samplingRate; + if (pFormat != NULL) *pFormat = format; + if (pChannels != NULL) *pChannels = channels; + if (pLatencyMs != NULL) *pLatencyMs = thread->latency(); // notify client processes of the new output creation thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED); @@ -5012,7 +5052,7 @@ status_t AudioFlinger::closeOutput(int output) } } } - void *param2 = 0; + void *param2 = NULL; audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2); mPlaybackThreads.removeItem(output); } @@ -5020,6 +5060,7 @@ status_t AudioFlinger::closeOutput(int output) if (thread->type() != ThreadBase::DUPLICATING) { AudioStreamOut *out = thread->clearOutput(); + assert(out != NULL); // from now on thread->mOutput is NULL out->hwDev->close_output_stream(out->hwDev, out->stream); delete out; @@ -5060,17 +5101,17 @@ status_t AudioFlinger::restoreOutput(int output) int AudioFlinger::openInput(uint32_t *pDevices, uint32_t *pSamplingRate, - uint32_t *pFormat, + audio_format_t *pFormat, uint32_t *pChannels, - uint32_t acoustics) + audio_in_acoustics_t acoustics) { status_t status; RecordThread *thread = NULL; uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; - uint32_t format = pFormat ? *pFormat : 0; + audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; uint32_t channels = pChannels ? *pChannels : 0; uint32_t reqSamplingRate = samplingRate; - uint32_t reqFormat = format; + audio_format_t reqFormat = format; uint32_t reqChannels = channels; audio_stream_in_t *inStream; audio_hw_device_t *inHwDev; @@ -5085,9 +5126,9 @@ int AudioFlinger::openInput(uint32_t *pDevices, if (inHwDev == NULL) return 0; - status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format, + status = inHwDev->open_input_stream(inHwDev, *pDevices, &format, &channels, &samplingRate, - (audio_in_acoustics_t)acoustics, + acoustics, &inStream); ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d", inStream, @@ -5105,9 +5146,9 @@ int AudioFlinger::openInput(uint32_t *pDevices, (samplingRate <= 2 * reqSamplingRate) && (popcount(channels) < 3) && (popcount(reqChannels) < 3)) { ALOGV("openInput() reopening with proposed sampling rate and channels"); - status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format, + status = inHwDev->open_input_stream(inHwDev, *pDevices, &format, &channels, &samplingRate, - (audio_in_acoustics_t)acoustics, + acoustics, &inStream); } @@ -5127,9 +5168,9 @@ int AudioFlinger::openInput(uint32_t *pDevices, device); mRecordThreads.add(id, thread); ALOGV("openInput() created record thread: ID %d thread %p", id, thread); - if (pSamplingRate) *pSamplingRate = reqSamplingRate; - if (pFormat) *pFormat = format; - if (pChannels) *pChannels = reqChannels; + if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate; + if (pFormat != NULL) *pFormat = format; + if (pChannels != NULL) *pChannels = reqChannels; input->stream->common.standby(&input->stream->common); @@ -5154,13 +5195,14 @@ status_t AudioFlinger::closeInput(int input) } ALOGV("closeInput() %d", input); - void *param2 = 0; + void *param2 = NULL; audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2); mRecordThreads.removeItem(input); } thread->exit(); AudioStreamIn *in = thread->clearInput(); + assert(in != NULL); // from now on thread->mInput is NULL in->hwDev->close_input_stream(in->hwDev, in->stream); delete in; @@ -5168,7 +5210,7 @@ status_t AudioFlinger::closeInput(int input) return NO_ERROR; } -status_t AudioFlinger::setStreamOutput(uint32_t stream, int output) +status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, int output) { Mutex::Autolock _l(mLock); MixerThread *dstThread = checkMixerThread_l(output); @@ -5215,12 +5257,8 @@ void AudioFlinger::acquireAudioSessionId(int audioSession) return; } } - AudioSessionRef *ref = new AudioSessionRef(); - ref->sessionid = audioSession; - ref->pid = caller; - ref->cnt = 1; - mAudioSessionRefs.push(ref); - ALOGV(" added new entry for %d", ref->sessionid); + mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller)); + ALOGV(" added new entry for %d", audioSession); } void AudioFlinger::releaseAudioSessionId(int audioSession) @@ -5736,7 +5774,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l( effect = chain->getEffectFromDesc_l(desc); } - ALOGV("createEffect_l() got effect %p on chain %p", effect == 0 ? 0 : effect.get(), chain.get()); + ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get()); if (effect == 0) { int id = mAudioFlinger->nextUniqueId(); @@ -5764,7 +5802,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l( // create effect handle and connect it to effect module handle = new EffectHandle(effect, client, effectClient, priority); lStatus = effect->addHandle(handle); - if (enabled) { + if (enabled != NULL) { *enabled = (int)effect->isEnabled(); } } @@ -5895,7 +5933,7 @@ sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int ses return chain; } -void AudioFlinger::ThreadBase::setMode(uint32_t mode) +void AudioFlinger::ThreadBase::setMode(audio_mode_t mode) { Mutex::Autolock _l(mLock); size_t size = mEffectChains.size(); @@ -6151,7 +6189,7 @@ AudioFlinger::EffectModule::~EffectModule() } } -status_t AudioFlinger::EffectModule::addHandle(sp<EffectHandle>& handle) +status_t AudioFlinger::EffectModule::addHandle(const sp<EffectHandle>& handle) { status_t status; @@ -6198,7 +6236,7 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle) bool enabled = false; EffectHandle *hdl = handle.unsafe_get(); - if (hdl) { + if (hdl != NULL) { ALOGV("removeHandle() unsafe_get OK"); enabled = hdl->enabled(); } @@ -6295,7 +6333,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); } @@ -6400,7 +6438,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, @@ -6693,7 +6731,7 @@ status_t AudioFlinger::EffectModule::setDevice(uint32_t device) return status; } -status_t AudioFlinger::EffectModule::setMode(uint32_t mode) +status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode) { Mutex::Autolock _l(mLock); status_t status = NO_ERROR; @@ -6702,7 +6740,7 @@ status_t AudioFlinger::EffectModule::setMode(uint32_t mode) uint32_t size = sizeof(status_t); status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_SET_AUDIO_MODE, - sizeof(int), + sizeof(audio_mode_t), &mode, &size, &cmdStatus); @@ -6718,7 +6756,8 @@ void AudioFlinger::EffectModule::setSuspended(bool suspended) Mutex::Autolock _l(mLock); mSuspended = suspended; } -bool AudioFlinger::EffectModule::suspended() + +bool AudioFlinger::EffectModule::suspended() const { Mutex::Autolock _l(mLock); return mSuspended; @@ -6833,7 +6872,7 @@ AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect, if (mCblkMemory != 0) { mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer()); - if (mCblk) { + if (mCblk != NULL) { new(mCblk) effect_param_cblk_t(); mBuffer = (uint8_t *)mCblk + bufOffset; } @@ -6930,7 +6969,7 @@ void AudioFlinger::EffectHandle::disconnect(bool unpiniflast) // release sp on module => module destructor can be called now mEffect.clear(); if (mClient != 0) { - if (mCblk) { + if (mCblk != NULL) { mCblk->~effect_param_cblk_t(); // destroy our shared-structure. } mCblkMemory.clear(); // and free the shared memory @@ -7060,7 +7099,7 @@ status_t AudioFlinger::EffectHandle::onTransact( void AudioFlinger::EffectHandle::dump(char* buffer, size_t size) { - bool locked = mCblk ? tryLock(mCblk->lock) : false; + bool locked = mCblk != NULL && tryLock(mCblk->lock); snprintf(buffer, size, "\t\t\t%05d %05d %01u %01u %05u %05u\n", (mClient == NULL) ? getpid() : mClient->pid(), @@ -7351,7 +7390,7 @@ void AudioFlinger::EffectChain::setDevice_l(uint32_t device) } // setMode_l() must be called with PlaybackThread::mLock held -void AudioFlinger::EffectChain::setMode_l(uint32_t mode) +void AudioFlinger::EffectChain::setMode_l(audio_mode_t mode) { size_t size = mEffects.size(); for (size_t i = 0; i < size; i++) { @@ -7522,7 +7561,8 @@ void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend) ALOGV("setEffectSuspendedAll_l() add entry for 0"); } if (desc->mRefCount++ == 0) { - Vector< sp<EffectModule> > effects = getSuspendEligibleEffects(); + Vector< sp<EffectModule> > effects; + getSuspendEligibleEffects(effects); for (size_t i = 0; i < effects.size(); i++) { setEffectSuspended_l(&effects[i]->desc().type, true); } @@ -7573,16 +7613,14 @@ bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descript return true; } -Vector< sp<AudioFlinger::EffectModule> > AudioFlinger::EffectChain::getSuspendEligibleEffects() +void AudioFlinger::EffectChain::getSuspendEligibleEffects(Vector< sp<AudioFlinger::EffectModule> > &effects) { - Vector< sp<EffectModule> > effects; + effects.clear(); for (size_t i = 0; i < mEffects.size(); i++) { - if (!isEffectEligibleForSuspend(mEffects[i]->desc())) { - continue; + if (isEffectEligibleForSuspend(mEffects[i]->desc())) { + effects.add(mEffects[i]); } - effects.add(mEffects[i]); } - return effects; } sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled( |