Add memcpy_to_p24_from_q8_23 and clamp24_from_q8_23
Change-Id: Ibe712c7b1e0fa4efd9a3e8f9dee11080f6c68941
diff --git a/audio_utils/include/audio_utils/primitives.h b/audio_utils/include/audio_utils/primitives.h
index 26dc63d..0b8ce44 100644
--- a/audio_utils/include/audio_utils/primitives.h
+++ b/audio_utils/include/audio_utils/primitives.h
@@ -165,6 +165,17 @@
*/
void memcpy_to_p24_from_float(uint8_t *dst, const float *src, size_t count);
+/* Copy samples from signed fixed-point 32-bit Q8.23 to signed fixed-point packed 24 bit Q0.23.
+ * The packed 24 bit output is assumed to be a little-endian uint8_t byte array.
+ * The data is clamped to the range is [0x800000, 0x7fffff].
+ * Parameters:
+ * dst Destination buffer
+ * src Source buffer
+ * count Number of samples to copy
+ * The destination and source buffers must be completely separate.
+ */
+void memcpy_to_p24_from_q8_23(uint8_t *dst, const int32_t *src, size_t count);
+
/* Copy samples from signed fixed point 16-bit Q0.15 to signed fixed-point 32-bit Q8.23.
* The output data range is [0xff800000, 0x007fff00] at intervals of 0x100.
* Parameters:
@@ -372,6 +383,24 @@
return f > 0 ? f + 0.5 : f - 0.5;
}
+/* Convert a signed fixed-point 32-bit Q8.23 value to a Q0.23 integer value,
+ * stored in a 32-bit signed integer (technically stored as Q8.23, but clamped to Q0.23).
+ *
+ * Values outside the range [-0x800000, 0x7fffff] are clamped to that range.
+ */
+static inline int32_t clamp24_from_q8_23(int32_t ival)
+{
+ static const int32_t limpos = 0x7fffff;
+ static const int32_t limneg = -0x800000;
+ if (ival < limneg) {
+ return limneg;
+ } else if (ival > limpos) {
+ return limpos;
+ } else {
+ return ival;
+ }
+}
+
/* Convert a single-precision floating point value to a Q4.27 integer value.
* Rounds to nearest, ties away from 0.
*
diff --git a/audio_utils/primitives.c b/audio_utils/primitives.c
index 443ed9c..1fc399b 100644
--- a/audio_utils/primitives.c
+++ b/audio_utils/primitives.c
@@ -126,6 +126,23 @@
}
}
+void memcpy_to_p24_from_q8_23(uint8_t *dst, const int32_t *src, size_t count)
+{
+ while (count--) {
+ int32_t ival = clamp24_from_q8_23(*src++);
+
+#ifdef HAVE_BIG_ENDIAN
+ *dst++ = ival >> 16;
+ *dst++ = ival >> 8;
+ *dst++ = ival;
+#else
+ *dst++ = ival;
+ *dst++ = ival >> 8;
+ *dst++ = ival >> 16;
+#endif
+ }
+}
+
void memcpy_to_q8_23_from_i16(int32_t *dst, const int16_t *src, size_t count)
{
while (count--) {