From 6146c08f0c3dd8b9e5788063aa433f304a810602 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Tue, 18 Mar 2014 11:56:15 -0700 Subject: Add enabling variable for extended precision audio Set AudioFlinger::kEnableExtendedPrecision = true to enable extended precision. Enabling will be required for devices (such as USB) which report 24 bit or 32 bit sink formats. Change-Id: I0dc1d7a4f7607086d7b536ea0e43aef0e696f2ee --- services/audioflinger/AudioFlinger.cpp | 19 ++++++++++++++++--- services/audioflinger/AudioFlinger.h | 18 ++++++++++++++++++ services/audioflinger/Threads.cpp | 16 +++++++++------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 527fd65..11a01cc 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1621,6 +1621,19 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module, mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; audio_stream_out_t *outStream = NULL; + + // FOR TESTING ONLY: + // Enable increased sink precision for mixing mode if kEnableExtendedPrecision is true. + if (kEnableExtendedPrecision && // Check only for Normal Mixing mode + !(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) { + // Update format + //config.format = AUDIO_FORMAT_PCM_FLOAT; + //config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED; + //config.format = AUDIO_FORMAT_PCM_32_BIT; + //config.format = AUDIO_FORMAT_PCM_8_24_BIT; + // ALOGV("openOutput() upgrading format to %#08x", config.format); + } + status_t status = hwDevHal->open_output_stream(hwDevHal, id, *pDevices, @@ -1644,9 +1657,9 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module, if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { thread = new OffloadThread(this, output, id, *pDevices); ALOGV("openOutput() created offload output: ID %d thread %p", id, thread); - } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) || - (config.format != AUDIO_FORMAT_PCM_16_BIT) || - (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) { + } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) + || !isValidPcmSinkFormat(config.format) + || (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) { thread = new DirectOutputThread(this, output, id, *pDevices); ALOGV("openOutput() created direct output: ID %d thread %p", id, thread); } else { diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 6e73a14..ddc6afb 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -326,6 +326,24 @@ private: audio_devices_t devices); void purgeStaleEffects_l(); + // Set kEnableExtendedPrecision to true to use extended precision in MixerThread + static const bool kEnableExtendedPrecision = false; + + // Returns true if format is permitted for the PCM sink in the MixerThread + static inline bool isValidPcmSinkFormat(audio_format_t format) { + switch (format) { + case AUDIO_FORMAT_PCM_16_BIT: + return true; + case AUDIO_FORMAT_PCM_FLOAT: + case AUDIO_FORMAT_PCM_24_BIT_PACKED: + case AUDIO_FORMAT_PCM_32_BIT: + case AUDIO_FORMAT_PCM_8_24_BIT: + return kEnableExtendedPrecision; + default: + return false; + } + } + // standby delay for MIXER and DUPLICATING playback threads is read from property // ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs static nsecs_t mStandbyTimeInNsecs; diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index d6390b1..792d722 100755 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1157,12 +1157,12 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp& audioFlinge type_t type) : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type), mNormalFrameCount(0), mSinkBuffer(NULL), - mMixerBufferEnabled(false), + mMixerBufferEnabled(AudioFlinger::kEnableExtendedPrecision), mMixerBuffer(NULL), mMixerBufferSize(0), mMixerBufferFormat(AUDIO_FORMAT_INVALID), mMixerBufferValid(false), - mEffectBufferEnabled(false), + mEffectBufferEnabled(AudioFlinger::kEnableExtendedPrecision), mEffectBuffer(NULL), mEffectBufferSize(0), mEffectBufferFormat(AUDIO_FORMAT_INVALID), @@ -1401,9 +1401,10 @@ sp AudioFlinger::PlaybackThread::createTrac frameCount, mFrameCount); } else { ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d " - "mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u " + "mFrameCount=%d format=%#x mFormat=%#x isLinear=%d channelMask=%#x " + "sampleRate=%u mSampleRate=%u " "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x", - isTimed, sharedBuffer.get(), frameCount, mFrameCount, format, + isTimed, sharedBuffer.get(), frameCount, mFrameCount, format, mFormat, audio_is_linear_pcm(format), channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask); *flags &= ~IAudioFlinger::TRACK_FAST; @@ -1809,9 +1810,10 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() if (!audio_is_valid_format(mFormat)) { LOG_ALWAYS_FATAL("HAL format %#x not valid for output", mFormat); } - if ((mType == MIXER || mType == DUPLICATING) && mFormat != AUDIO_FORMAT_PCM_16_BIT) { - LOG_ALWAYS_FATAL("HAL format %#x not supported for mixed output; " - "must be AUDIO_FORMAT_PCM_16_BIT", mFormat); + if ((mType == MIXER || mType == DUPLICATING) + && !isValidPcmSinkFormat(mFormat)) { + LOG_FATAL("HAL format %#x not supported for mixed output", + mFormat); } mFrameSize = audio_stream_frame_size(&mOutput->stream->common); mBufferSize = mOutput->stream->common.get_buffer_size(&mOutput->stream->common); -- cgit v1.1