audio_utils primitives: Add float clamping memcopy
For security reason, float buffers provided by application must be
clamped to FLOAT_NOMINAL_RANGE_HEADROOM.
With the new all float pipeline, float are no longer clamped by their
conversion to fixed point.
This patch adds a function to efficiently clamp a buffer during a
memcopy.
Test: adb shell /system/bin/primitives_benchmark
Test: adb shell /data/nativetest/primitives_tests/primitives_tests --gtest_filter=*Clamping*
Bug: 68099072
Change-Id: I030b247ea29cb94c62d1206c31960f45da2446e6
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/audio_utils/primitives.c b/audio_utils/primitives.c
index 9a4cc3b..77d4f34 100644
--- a/audio_utils/primitives.c
+++ b/audio_utils/primitives.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <math.h>
#include <cutils/bitops.h> /* for popcount() */
#include <audio_utils/primitives.h>
#include "private/private.h"
@@ -256,6 +257,18 @@
}
}
+void memcpy_to_float_from_float_with_clamping(float *dst, const float *src, size_t count,
+ float absMax) {
+ // Note: using NEON intrinsics (vminq_f32, vld1q_f32...) did NOT accelerate
+ // the function when benchmarked. The compiler already vectorize using FMINNM f32x4 & similar.
+ // Note: clamping induce a ~20% overhead compared to memcpy for count in [64, 512]
+ // See primitives_benchmark
+ while (count--) {
+ const float sample = *src++;
+ *dst++ = fmax(-absMax, fmin(absMax, sample));
+ }
+}
+
void downmix_to_mono_i16_from_stereo_i16(int16_t *dst, const int16_t *src, size_t count)
{
while (count--) {