Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba9a1070 authored by Atneya Nair's avatar Atneya Nair
Browse files

Clamp float data sent to HAL

When memcpying from float to float, we don't check for values
above unity, including NaN. In all other PCM cases, we clamp on either
side of the conversion.

Prior to writing to the HAL, check the data to insulate HALs
which may not tolerate invalid float PCM data gracefully.

Bug: 247119066
Test: atest AudioTrackTest
Change-Id: I355c98f94b1bc9e340f609348ba1b9184c0fd1e3
parent cce14202
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -4103,10 +4103,19 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                                       mEffectBufferFormat,
                                       mNormalFrameCount * mHapticChannelCount);
            }

            memcpy_by_audio_format(mSinkBuffer, mFormat, effectBuffer, mEffectBufferFormat,
                    mNormalFrameCount * (mChannelCount + mHapticChannelCount));

            const size_t framesToCopy = mNormalFrameCount * (mChannelCount + mHapticChannelCount);
            if (mFormat == AUDIO_FORMAT_PCM_FLOAT &&
                    mEffectBufferFormat == AUDIO_FORMAT_PCM_FLOAT) {
                // Clamp PCM float values more than this distance from 0 to insulate
                // a HAL which doesn't handle NaN correctly.
                static constexpr float HAL_FLOAT_SAMPLE_LIMIT = 2.0f;
                memcpy_to_float_from_float_with_clamping(static_cast<float*>(mSinkBuffer),
                        static_cast<const float*>(effectBuffer),
                        framesToCopy, HAL_FLOAT_SAMPLE_LIMIT /* absMax */);
            } else {
                memcpy_by_audio_format(mSinkBuffer, mFormat,
                        effectBuffer, mEffectBufferFormat, framesToCopy);
            }
            // The sample data is partially interleaved when haptic channels exist,
            // we need to adjust channels here.
            if (mHapticChannelCount > 0) {