audio_utils: Support more format conversions

Support conversion from 32 bit pcm to 24 bit packed pcm.
Support conversion from 8_24 bit to 24 bit packed pcm.
Support conversion from 24 bit packed pcm to 32 bit pcm.

authored-by: Ashish Jain <ashishj@codeaurora.org>

Change-Id: I328ef6ed865f73e49be50ffa1b4e07e865df0339
diff --git a/audio_utils/format.c b/audio_utils/format.c
index 66b0a6d..3eda484 100644
--- a/audio_utils/format.c
+++ b/audio_utils/format.c
@@ -102,6 +102,12 @@
         case AUDIO_FORMAT_PCM_FLOAT:
             memcpy_to_p24_from_float((uint8_t*)dst, (float*)src, count);
             return;
+        case AUDIO_FORMAT_PCM_32_BIT:
+            memcpy_to_p24_from_i32((uint8_t*)dst, (int32_t*)src, count);
+            return;
+        case AUDIO_FORMAT_PCM_8_24_BIT:
+            memcpy_to_p24_from_q8_23((uint8_t*)dst, (int32_t*)src, count);
+            return;
         default:
             break;
         }
@@ -114,6 +120,9 @@
         case AUDIO_FORMAT_PCM_FLOAT:
             memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count);
             return;
+        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+            memcpy_to_i32_from_p24((int32_t*)dst, (uint8_t *)src, count);
+            return;
         default:
             break;
         }
diff --git a/audio_utils/tests/primitives_tests.cpp b/audio_utils/tests/primitives_tests.cpp
index 5b3cd2d..178490b 100644
--- a/audio_utils/tests/primitives_tests.cpp
+++ b/audio_utils/tests/primitives_tests.cpp
@@ -103,6 +103,14 @@
     }
 }
 
+void checkMonotonep24(uint8_t * pary, size_t size)
+{
+    size_t frames = size/3;
+    for (size_t i = 1; i < frames; ++i) {
+        EXPECT_LT(i32_from_p24(pary + 3*(i-1)), i32_from_p24(pary + 3*i));
+    }
+}
+
 TEST(audio_utils_primitives, clamp_to_int) {
     static const float testArray[] = {
             -NAN, -INFINITY,
@@ -256,6 +264,31 @@
     memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
     checkMonotone(i16ary, 65536);
 
+    // do round-trip test i16 -> p24 -> i32 -> p24 -> q8_23 -> p24 -> i16
+    memcpy_to_p24_from_i16(pary, i16ary, 65536);
+    memset(i16ary, 0, 65536 * sizeof(i16ary[0]));
+    checkMonotonep24(pary, 65536 * 3);
+
+    memcpy_to_i32_from_p24(i32ary, pary, 65536);
+    memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+    checkMonotone(i32ary, 65536);
+
+    memcpy_to_p24_from_i32(pary, i32ary, 65536);
+    memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
+    checkMonotonep24(pary, 65536 * 3);
+
+    memcpy_to_q8_23_from_p24(i32ary, pary, 65536);
+    memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+    checkMonotone(i32ary, 65536);
+
+    memcpy_to_p24_from_q8_23(pary, i32ary, 65536);
+    memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
+    checkMonotonep24(pary, 65536 * 3);
+
+    memcpy_to_i16_from_p24(i16ary, pary, 65536);
+    memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+    checkMonotone(i16ary, 65536);
+
     // do partial round-trip testing q4_27 to i16 and float
     memcpy_to_float_from_i16(fary, i16ary, 65536);
     //memset(i16ary, 0, 65536 * sizeof(i16ary[0])); // not cleared: we don't do full roundtrip