summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
Diffstat (limited to 'services/audioflinger')
-rw-r--r--services/audioflinger/AudioMixerOps.h5
-rw-r--r--services/audioflinger/FastMixer.cpp4
-rw-r--r--services/audioflinger/SpdifStreamOut.cpp3
-rw-r--r--services/audioflinger/Threads.cpp17
-rw-r--r--services/audioflinger/Threads.h2
5 files changed, 25 insertions, 6 deletions
diff --git a/services/audioflinger/AudioMixerOps.h b/services/audioflinger/AudioMixerOps.h
index 2678857..8d74024 100644
--- a/services/audioflinger/AudioMixerOps.h
+++ b/services/audioflinger/AudioMixerOps.h
@@ -164,13 +164,12 @@ inline int32_t MixMul<int32_t, int16_t, float>(int16_t value, float volume) {
template <>
inline int16_t MixMul<int16_t, int16_t, float>(int16_t value, float volume) {
LOG_ALWAYS_FATAL("MixMul<int16_t, int16_t, float> Runtime Should not be here");
- return value * volume;
+ return clamp16_from_float(MixMul<float, int16_t, float>(value, volume));
}
template <>
inline int16_t MixMul<int16_t, float, float>(float value, float volume) {
- static const float q_15_from_float = (1 << 15);
- return value * volume * q_15_from_float;
+ return clamp16_from_float(value * volume);
}
/*
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index f1cf0aa..45c68b5 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -177,6 +177,10 @@ void FastMixer::onStateChange()
free(mSinkBuffer);
mSinkBuffer = NULL;
if (frameCount > 0 && mSampleRate > 0) {
+ // The mixer produces either 16 bit PCM or float output, select
+ // float output if the HAL supports higher than 16 bit precision.
+ mMixerBufferFormat = mFormat.mFormat == AUDIO_FORMAT_PCM_16_BIT ?
+ AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT;
// FIXME new may block for unbounded time at internal mutex of the heap
// implementation; it would be better to have normal mixer allocate for us
// to avoid blocking here and to prevent possible priority inversion
diff --git a/services/audioflinger/SpdifStreamOut.cpp b/services/audioflinger/SpdifStreamOut.cpp
index 45b541a..ac637ef 100644
--- a/services/audioflinger/SpdifStreamOut.cpp
+++ b/services/audioflinger/SpdifStreamOut.cpp
@@ -128,7 +128,7 @@ status_t SpdifStreamOut::getRenderPosition(uint32_t *frames)
int SpdifStreamOut::flush()
{
- // FIXME Is there an issue here with flush being asynchronous?
+ mSpdifEncoder.reset();
mRenderPositionHal = 0;
mPreviousHalPosition32 = 0;
return AudioStreamOut::flush();
@@ -136,6 +136,7 @@ int SpdifStreamOut::flush()
int SpdifStreamOut::standby()
{
+ mSpdifEncoder.reset();
mRenderPositionHal = 0;
mPreviousHalPosition32 = 0;
return AudioStreamOut::standby();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 489f2d4..410fff5 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2194,6 +2194,8 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()
// Check if we want to throttle the processing to no more than 2x normal rate
mThreadThrottle = property_get_bool("af.thread.throttle", true /* default_value */);
+ mThreadThrottleTimeMs = 0;
+ mThreadThrottleEndMs = 0;
mHalfBufferMs = mNormalFrameCount * 1000 / (2 * mSampleRate);
// mSinkBuffer is the sink buffer. Size is always multiple-of-16 frames.
@@ -2960,8 +2962,19 @@ bool AudioFlinger::PlaybackThread::threadLoop()
const int32_t throttleMs = mHalfBufferMs - deltaMs;
if ((signed)mHalfBufferMs >= throttleMs && throttleMs > 0) {
usleep(throttleMs * 1000);
- ALOGD("mixer(%p) throttle: ret(%zd) deltaMs(%d) requires sleep %d ms",
+ // notify of throttle start on verbose log
+ ALOGV_IF(mThreadThrottleEndMs == mThreadThrottleTimeMs,
+ "mixer(%p) throttle begin:"
+ " ret(%zd) deltaMs(%d) requires sleep %d ms",
this, ret, deltaMs, throttleMs);
+ mThreadThrottleTimeMs += throttleMs;
+ } else {
+ uint32_t diff = mThreadThrottleTimeMs - mThreadThrottleEndMs;
+ if (diff > 0) {
+ // notify of throttle end on debug log
+ ALOGD("mixer(%p) throttle end: throttle time(%u)", this, diff);
+ mThreadThrottleEndMs = mThreadThrottleTimeMs;
+ }
}
}
}
@@ -4340,7 +4353,7 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar
String8 result;
PlaybackThread::dumpInternals(fd, args);
-
+ dprintf(fd, " Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs);
dprintf(fd, " AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
// Make a non-atomic copy of fast mixer dump state so it won't change underneath us
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 4ebe615..b12b091 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -614,6 +614,8 @@ protected:
size_t mNormalFrameCount; // normal mixer and effects
bool mThreadThrottle; // throttle the thread processing
+ uint32_t mThreadThrottleTimeMs; // throttle time for MIXER threads
+ uint32_t mThreadThrottleEndMs; // notify once per throttling
uint32_t mHalfBufferMs; // half the buffer size in milliseconds
void* mSinkBuffer; // frame size aligned sink buffer