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

Commit 68436cf9 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
Bug: 241662887
Test: atest AudioTrackTest
Change-Id: I355c98f94b1bc9e340f609348ba1b9184c0fd1e3
(cherry picked from commit ba9a1070)
parent 36af0f66
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -4102,10 +4102,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) {