1b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung/* 2b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * Copyright (C) 2014 The Android Open Source Project 3b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * 4b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * Licensed under the Apache License, Version 2.0 (the "License"); 5b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * you may not use this file except in compliance with the License. 6b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * You may obtain a copy of the License at 7b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * 8b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * http://www.apache.org/licenses/LICENSE-2.0 9b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * 10b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * Unless required by applicable law or agreed to in writing, software 11b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * distributed under the License is distributed on an "AS IS" BASIS, 12b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * See the License for the specific language governing permissions and 14b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung * limitations under the License. 15b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung */ 16b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 17b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung//#define LOG_NDEBUG 0 18b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#define LOG_TAG "audio_utils_primitives_tests" 19b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 20f476054361310110757909bd63b022bca32ec649Dan Albert#include <math.h> 21b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#include <vector> 228198c3b752e2fb00acb15345496e2a03eefb5ffbMark Salyzyn 23b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#include <gtest/gtest.h> 244df5a2bb302fb5cb61ab48dff7fa2b1984b6ced8Mark Salyzyn#include <log/log.h> 258198c3b752e2fb00acb15345496e2a03eefb5ffbMark Salyzyn 26b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#include <audio_utils/primitives.h> 27b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#include <audio_utils/format.h> 28e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung#include <audio_utils/channels.h> 29b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 30b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 31b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 3210a7d323d942d143f5298010e228f3f8ff7c8328Andy Hungstatic const int32_t lim8pos = 255; 3310a7d323d942d143f5298010e228f3f8ff7c8328Andy Hungstatic const int32_t lim8neg = 0; 34b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hungstatic const int32_t lim16pos = (1 << 15) - 1; 35b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hungstatic const int32_t lim16neg = -(1 << 15); 36b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hungstatic const int32_t lim24pos = (1 << 23) - 1; 37b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hungstatic const int32_t lim24neg = -(1 << 23); 38b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 3910a7d323d942d143f5298010e228f3f8ff7c8328Andy Hunginline void testClamp8(float f) 4010a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung{ 4110a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung // f is in native u8 scaling to test rounding 4210a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung uint8_t uval = clamp8_from_float((f - 128) / (1 << 7)); 4310a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 4410a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung // test clamping 4510a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung ALOGV("clamp8_from_float(%f) = %u\n", f, uval); 4610a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung if (f > lim8pos) { 4710a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung EXPECT_EQ(lim8pos, uval); 4810a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung } else if (f < lim8neg) { 4910a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung EXPECT_EQ(lim8neg, uval); 5010a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung } 5110a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 5210a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung // if in range, make sure round trip clamp and conversion is correct. 5310a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung if (f < lim8pos - 1. && f > lim8neg + 1.) { 5410a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung uint8_t uval2 = clamp8_from_float(float_from_u8(uval)); 5510a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung int diff = abs(uval - uval2); 5610a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung EXPECT_LE(diff, 1); 5710a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung } 5810a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung} 5910a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 60b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hunginline void testClamp16(float f) 61b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung{ 6265b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hung int16_t ival = clamp16_from_float(f / (1 << 15)); 63b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 64b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // test clamping 65b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung ALOGV("clamp16_from_float(%f) = %d\n", f, ival); 66b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung if (f > lim16pos) { 67bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(lim16pos, ival); 68b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } else if (f < lim16neg) { 69bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(lim16neg, ival); 70b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 71b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 72b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // if in range, make sure round trip clamp and conversion is correct. 73b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung if (f < lim16pos - 1. && f > lim16neg + 1.) { 7465b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hung int ival2 = clamp16_from_float(float_from_i16(ival)); 75b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung int diff = abs(ival - ival2); 76b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung EXPECT_LE(diff, 1); 77b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 78b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung} 79b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 80b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hunginline void testClamp24(float f) 81b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung{ 82b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung int32_t ival = clamp24_from_float(f / (1 << 23)); 83b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 84b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // test clamping 85b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung ALOGV("clamp24_from_float(%f) = %d\n", f, ival); 86b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung if (f > lim24pos) { 87bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(lim24pos, ival); 88b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } else if (f < lim24neg) { 89bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(lim24neg, ival); 90b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 91b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 92b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // if in range, make sure round trip clamp and conversion is correct. 93b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung if (f < lim24pos - 1. && f > lim24neg + 1.) { 94b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung int ival2 = clamp24_from_float(float_from_q8_23(ival)); 95b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung int diff = abs(ival - ival2); 96b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung EXPECT_LE(diff, 1); 97b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 98b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung} 99b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 100b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungtemplate<typename T> 101b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungvoid checkMonotone(const T *ary, size_t size) 102b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung{ 103b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung for (size_t i = 1; i < size; ++i) { 104b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung EXPECT_LT(ary[i-1], ary[i]); 105b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } 106b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung} 107b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 108bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew Georgevoid checkMonotonep24(uint8_t * pary, size_t size) 109bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George{ 110bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George size_t frames = size/3; 111bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George for (size_t i = 1; i < frames; ++i) { 112bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George EXPECT_LT(i32_from_p24(pary + 3*(i-1)), i32_from_p24(pary + 3*i)); 113bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George } 114bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George} 115bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 116b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy HungTEST(audio_utils_primitives, clamp_to_int) { 117b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung static const float testArray[] = { 118b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung -NAN, -INFINITY, 119b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung -1.e20, -32768., 63.9, 120b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung -3.5, -3.4, -2.5, 2.4, -1.5, -1.4, -0.5, -0.2, 0., 0.2, 0.5, 0.8, 121b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 1.4, 1.5, 1.8, 2.4, 2.5, 2.6, 3.4, 3.5, 122b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 32767., 32768., 1.e20, 123b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung INFINITY, NAN }; 124b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 125b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung for (size_t i = 0; i < ARRAY_SIZE(testArray); ++i) { 12610a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung testClamp8(testArray[i]); 12710a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung } 12810a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung for (size_t i = 0; i < ARRAY_SIZE(testArray); ++i) { 129b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung testClamp16(testArray[i]); 130b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 131b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung for (size_t i = 0; i < ARRAY_SIZE(testArray); ++i) { 132b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung testClamp24(testArray[i]); 133b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 134b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 135b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung // used for ULP testing (tweaking the lsb of the float) 136b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung union { 137b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung int32_t i; 138b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung float f; 139b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } val; 140b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung int32_t res; 141b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 142b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung // check clampq4_27_from_float() 143b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung val.f = 16.; 144b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung res = clampq4_27_from_float(val.f); 145bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0x7fffffff, res); 146b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung val.i--; 147b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung res = clampq4_27_from_float(val.f); 148b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung EXPECT_LE(res, 0x7fffffff); 149b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung EXPECT_GE(res, 0x7fff0000); 150b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung val.f = -16.; 151b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung res = clampq4_27_from_float(val.f); 152bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((int32_t)0x80000000, res); // negative 153b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung val.i++; 154b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung res = clampq4_27_from_float(val.f); 155b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung EXPECT_GE(res, (int32_t)0x80000000); // negative 156b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung EXPECT_LE(res, (int32_t)0x80008000); // negative 157de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 158de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung // check u4_28_from_float and u4_12_from_float 159de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung uint32_t ures; 160de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung uint16_t ures16; 161de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung val.f = 16.; 162de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung ures = u4_28_from_float(val.f); 163bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0xffffffff, ures); 164de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung ures16 = u4_12_from_float(val.f); 165bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0xffff, ures16); 166de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 167de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung val.f = -1.; 168de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung ures = u4_28_from_float(val.f); 169bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((uint32_t)0, ures); 170de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung ures16 = u4_12_from_float(val.f); 171bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0, ures16); 172de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 173de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung // check float_from_u4_28 and float_from_u4_12 (roundtrip) 174de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung for (uint32_t v = 0x100000; v <= 0xff000000; v += 0x100000) { 175de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung ures = u4_28_from_float(float_from_u4_28(v)); 176de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung EXPECT_EQ(ures, v); 177de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } 178de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung for (uint32_t v = 0; v <= 0xffff; ++v) { // uint32_t prevents overflow 179de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung ures16 = u4_12_from_float(float_from_u4_12(v)); 180de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung EXPECT_EQ(ures16, v); 181de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } 18210a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 18310a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung // check infinity 18410a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung EXPECT_EQ(0, clamp8_from_float(-INFINITY)); 18510a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung EXPECT_EQ(255, clamp8_from_float(INFINITY)); 186b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung} 187b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 188b533bd205c5a0dd35736cf4d46bda804175899c5Andy HungTEST(audio_utils_primitives, memcpy) { 189b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // test round-trip. 190b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung int16_t *i16ref = new int16_t[65536]; 191b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung int16_t *i16ary = new int16_t[65536]; 192b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung int32_t *i32ary = new int32_t[65536]; 193b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung float *fary = new float[65536]; 194b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung uint8_t *pary = new uint8_t[65536*3]; 195b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 196b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung for (size_t i = 0; i < 65536; ++i) { 197b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung i16ref[i] = i16ary[i] = i - 32768; 198b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung } 199b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 200b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // do round-trip testing i16 and float 201b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_float_from_i16(fary, i16ary, 65536); 202b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i16ary, 0, 65536 * sizeof(i16ary[0])); 203b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(fary, 65536); 204b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 205b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_i16_from_float(i16ary, fary, 65536); 206b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(fary, 0, 65536 * sizeof(fary[0])); 207b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i16ary, 65536); 208b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 209b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // TODO make a template case for the following? 210b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 211b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // do round-trip testing p24 to i16 and float 212b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_p24_from_i16(pary, i16ary, 65536); 213b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i16ary, 0, 65536 * sizeof(i16ary[0])); 214b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 215b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // check an intermediate format at a position(???) 216b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#if 0 217b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung printf("pary[%d].0 = %u pary[%d].1 = %u pary[%d].2 = %u\n", 218b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 1025, (unsigned) pary[1025*3], 219b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 1025, (unsigned) pary[1025*3+1], 220b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 1025, (unsigned) pary[1025*3+2] 221b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung ); 222b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung#endif 223b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 224b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_float_from_p24(fary, pary, 65536); 225b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(pary, 0, 65536 * 3 * sizeof(pary[0])); 226b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(fary, 65536); 227b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 228b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_p24_from_float(pary, fary, 65536); 229b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(fary, 0, 65536 * sizeof(fary[0])); 230b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 231b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_i16_from_p24(i16ary, pary, 65536); 232b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(pary, 0, 65536 * 3 * sizeof(pary[0])); 233b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i16ary, 65536); 234b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 235b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // do round-trip testing q8_23 to i16 and float 236b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_q8_23_from_i16(i32ary, i16ary, 65536); 237b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i16ary, 0, 65536 * sizeof(i16ary[0])); 238b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i32ary, 65536); 239b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 240b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_float_from_q8_23(fary, i32ary, 65536); 241b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 242b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(fary, 65536); 243b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 244b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_q8_23_from_float_with_clamp(i32ary, fary, 65536); 245b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(fary, 0, 65536 * sizeof(fary[0])); 246b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i32ary, 65536); 247b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 248b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_i16_from_q8_23(i16ary, i32ary, 65536); 249b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 250b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i16ary, 65536); 251b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 252b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung // do round-trip testing i32 to i16 and float 253b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_i32_from_i16(i32ary, i16ary, 65536); 254b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i16ary, 0, 65536 * sizeof(i16ary[0])); 255b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i32ary, 65536); 256b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 257b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_float_from_i32(fary, i32ary, 65536); 258b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 259b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(fary, 65536); 260b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 261b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_i32_from_float(i32ary, fary, 65536); 262b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(fary, 0, 65536 * sizeof(fary[0])); 263b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i32ary, 65536); 264b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 265b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memcpy_to_i16_from_i32(i16ary, i32ary, 65536); 266b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 267b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i16ary, 65536); 268b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 269bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George // do round-trip test i16 -> p24 -> i32 -> p24 -> q8_23 -> p24 -> i16 270bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_p24_from_i16(pary, i16ary, 65536); 271bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memset(i16ary, 0, 65536 * sizeof(i16ary[0])); 272bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George checkMonotonep24(pary, 65536 * 3); 273bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 274bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_i32_from_p24(i32ary, pary, 65536); 275bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memset(pary, 0, 65536 * 3 * sizeof(pary[0])); 276bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George checkMonotone(i32ary, 65536); 277bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 278bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_p24_from_i32(pary, i32ary, 65536); 279bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 280bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George checkMonotonep24(pary, 65536 * 3); 281bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 282bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_q8_23_from_p24(i32ary, pary, 65536); 283bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memset(pary, 0, 65536 * 3 * sizeof(pary[0])); 284bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George checkMonotone(i32ary, 65536); 285bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 286bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_p24_from_q8_23(pary, i32ary, 65536); 287bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 288bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George checkMonotonep24(pary, 65536 * 3); 289bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 290bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_i16_from_p24(i16ary, pary, 65536); 291bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memset(pary, 0, 65536 * 3 * sizeof(pary[0])); 292bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George checkMonotone(i16ary, 65536); 293bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George 294b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung // do partial round-trip testing q4_27 to i16 and float 295b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung memcpy_to_float_from_i16(fary, i16ary, 65536); 296b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung //memset(i16ary, 0, 65536 * sizeof(i16ary[0])); // not cleared: we don't do full roundtrip 297b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 298b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung memcpy_to_q4_27_from_float(i32ary, fary, 65536); 299b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung memset(fary, 0, 65536 * sizeof(fary[0])); 300b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(i32ary, 65536); 301b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 302b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung memcpy_to_float_from_q4_27(fary, i32ary, 65536); 303b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung memset(i32ary, 0, 65536 * sizeof(i32ary[0])); 304b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung checkMonotone(fary, 65536); 305b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 306b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung // at the end, our i16ary must be the same. (Monotone should be equivalent to this) 307bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0, memcmp(i16ary, i16ref, 65536*sizeof(i16ary[0]))); 308b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung 30910a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung // test round-trip for u8 and float. 31010a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung uint8_t *u8ref = new uint8_t[256]; 31110a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung uint8_t *u8ary = new uint8_t[256]; 31210a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 31310a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung for (unsigned i = 0; i < 256; ++i) { 31410a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung u8ref[i] = i; 31510a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung } 31610a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 31710a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung memcpy_to_float_from_u8(fary, u8ref, 256); 31810a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung memcpy_to_u8_from_float(u8ary, fary, 256); 31910a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 32010a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung EXPECT_EQ(0, memcmp(u8ary, u8ref, 256 * sizeof(u8ary[0]))); 32110a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung 32210a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung delete[] u8ref; 32310a7d323d942d143f5298010e228f3f8ff7c8328Andy Hung delete[] u8ary; 324b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung delete[] i16ref; 325b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung delete[] i16ary; 326b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung delete[] i32ary; 327b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung delete[] fary; 328b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung delete[] pary; 329b533bd205c5a0dd35736cf4d46bda804175899c5Andy Hung} 3303af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3313af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungtemplate<typename T> 3323af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungvoid checkMonotoneOrZero(const T *ary, size_t size) 3333af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung{ 3343af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung T least = 0; 3353af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3363af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung for (size_t i = 1; i < size; ++i) { 3373af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung if (ary[i]) { 3383af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung EXPECT_LT(least, ary[i]); 3393af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung least = ary[i]; 3403af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung } 3413af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung } 3423af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung} 3433af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3443af2af2518dc5534c94285e77d39d0fc729ed917Andy HungTEST(audio_utils_primitives, memcpy_by_channel_mask) { 3453af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t dst_mask; 3463af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t src_mask; 3473af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint16_t *u16ref = new uint16_t[65536]; 3483af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint16_t *u16ary = new uint16_t[65536]; 3493af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3503af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung for (size_t i = 0; i < 65536; ++i) { 3513af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung u16ref[i] = i; 3523af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung } 3533af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3543af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test when src mask is 0. Everything copied is zero. 3553af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0; 3563af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0x8d; 3573af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u16ary, 0x99, 65536 * sizeof(u16ref[0])); 3583af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask(u16ary, dst_mask, u16ref, src_mask, sizeof(u16ref[0]), 3593af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536 / popcount(dst_mask)); 360bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 3613af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3623af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test when dst_mask is 0. Nothing should be copied. 3633af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0; 3643af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0; 3653af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u16ary, 0, 65536 * sizeof(u16ref[0])); 3663af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask(u16ary, dst_mask, u16ref, src_mask, sizeof(u16ref[0]), 3673af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536); 368bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 3693af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3703af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test when masks are the same. One to one copy. 3713af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = dst_mask = 0x8d; 3723af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u16ary, 0x99, 65536 * sizeof(u16ref[0])); 3733af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask(u16ary, dst_mask, u16ref, src_mask, sizeof(u16ref[0]), 555); 374bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0, memcmp(u16ary, u16ref, 555 * sizeof(u16ref[0]) * popcount(dst_mask))); 3753af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3763af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test with a gap in source: 3773af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Input 3 samples, output 4 samples, one zero inserted. 3783af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0x8c; 3793af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0x8d; 3803af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u16ary, 0x9, 65536 * sizeof(u16ary[0])); 3813af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask(u16ary, dst_mask, u16ref, src_mask, sizeof(u16ref[0]), 3823af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536 / popcount(dst_mask)); 3833af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung checkMonotoneOrZero(u16ary, 65536); 384bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)(65536 * 3 / 4 - 1), nonZeroMono16((int16_t*)u16ary, 65536)); 3853af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3863af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test with a gap in destination: 3873af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Input 4 samples, output 3 samples, one deleted 3883af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0x8d; 3893af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0x8c; 3903af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u16ary, 0x9, 65536 * sizeof(u16ary[0])); 3913af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask(u16ary, dst_mask, u16ref, src_mask, sizeof(u16ref[0]), 3923af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536 / popcount(src_mask)); 3933af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung checkMonotone(u16ary, 65536 * 3 / 4); 3943af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3953af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung delete[] u16ref; 3963af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung delete[] u16ary; 3973af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung} 3983af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3993af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungvoid memcpy_by_channel_mask2(void *dst, uint32_t dst_mask, 4003af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const void *src, uint32_t src_mask, size_t sample_size, size_t count) 4013af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung{ 4023af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung int8_t idxary[32]; 4033af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t src_channels = popcount(src_mask); 4043af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t dst_channels = 4053af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_index_array_initialization(idxary, 32, dst_mask, src_mask); 4063af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4073af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_index_array(dst, dst_channels, src, src_channels, idxary, sample_size, count); 4083af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung} 4093af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4103af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung// a modified version of the memcpy_by_channel_mask test 4113af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung// but using 24 bit type and memcpy_by_index_array() 4123af2af2518dc5534c94285e77d39d0fc729ed917Andy HungTEST(audio_utils_primitives, memcpy_by_index_array) { 4133af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t dst_mask; 4143af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t src_mask; 4153af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung typedef struct {uint8_t c[3];} __attribute__((__packed__)) uint8x3_t; 4163af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint8x3_t *u24ref = new uint8x3_t[65536]; 4173af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint8x3_t *u24ary = new uint8x3_t[65536]; 4183af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint16_t *u16ref = new uint16_t[65536]; 4193af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint16_t *u16ary = new uint16_t[65536]; 4203af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 421bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)3, sizeof(uint8x3_t)); // 3 bytes per struct 4223af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4233af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // tests prepare_index_array_from_masks() 424bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)4, memcpy_by_index_array_initialization(NULL, 0, 0x8d, 0x8c)); 425bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)3, memcpy_by_index_array_initialization(NULL, 0, 0x8c, 0x8d)); 4263af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4273af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung for (size_t i = 0; i < 65536; ++i) { 4283af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung u16ref[i] = i; 4293af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung } 4303af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_to_p24_from_i16((uint8_t*)u24ref, (int16_t*)u16ref, 65536); 4313af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4323af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test when src mask is 0. Everything copied is zero. 4333af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0; 4343af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0x8d; 4353af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 4363af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 4373af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536 / popcount(dst_mask)); 4383af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 439bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 4403af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4413af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test when dst_mask is 0. Nothing should be copied. 4423af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0; 4433af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0; 4443af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u24ary, 0, 65536 * sizeof(u24ary[0])); 4453af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 4463af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536); 4473af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 448bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 4493af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4503af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test when masks are the same. One to one copy. 4513af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = dst_mask = 0x8d; 4523af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 4533af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 555); 454bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0, memcmp(u24ary, u24ref, 555 * sizeof(u24ref[0]) * popcount(dst_mask))); 4553af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4563af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test with a gap in source: 4573af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Input 3 samples, output 4 samples, one zero inserted. 4583af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0x8c; 4593af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0x8d; 4603af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u24ary, 0x9, 65536 * sizeof(u24ary[0])); 4613af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 4623af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536 / popcount(dst_mask)); 4633af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 4643af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung checkMonotoneOrZero(u16ary, 65536); 465bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ((size_t)(65536 * 3 / 4 - 1), nonZeroMono16((int16_t*)u16ary, 65536)); 4663af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4673af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Test with a gap in destination: 4683af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung // Input 4 samples, output 3 samples, one deleted 4693af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung src_mask = 0x8d; 4703af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung dst_mask = 0x8c; 4713af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memset(u24ary, 0x9, 65536 * sizeof(u24ary[0])); 4723af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_by_channel_mask2(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 4733af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 65536 / popcount(src_mask)); 4743af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 4753af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung checkMonotone(u16ary, 65536 * 3 / 4); 476291a1948093850aa87f60264680404b2b96ee327Andy Hung 477291a1948093850aa87f60264680404b2b96ee327Andy Hung delete[] u16ref; 478291a1948093850aa87f60264680404b2b96ee327Andy Hung delete[] u16ary; 479291a1948093850aa87f60264680404b2b96ee327Andy Hung delete[] u24ref; 480291a1948093850aa87f60264680404b2b96ee327Andy Hung delete[] u24ary; 481291a1948093850aa87f60264680404b2b96ee327Andy Hung} 482291a1948093850aa87f60264680404b2b96ee327Andy Hung 483291a1948093850aa87f60264680404b2b96ee327Andy Hungvoid memcpy_by_channel_mask_dst_index(void *dst, uint32_t dst_mask, 484291a1948093850aa87f60264680404b2b96ee327Andy Hung const void *src, uint32_t src_mask, size_t sample_size, size_t count) 485291a1948093850aa87f60264680404b2b96ee327Andy Hung{ 486291a1948093850aa87f60264680404b2b96ee327Andy Hung int8_t idxary[32]; 487291a1948093850aa87f60264680404b2b96ee327Andy Hung uint32_t src_channels = popcount(src_mask); 488291a1948093850aa87f60264680404b2b96ee327Andy Hung uint32_t dst_channels = 489291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_index_array_initialization_dst_index(idxary, 32, dst_mask, src_mask); 490291a1948093850aa87f60264680404b2b96ee327Andy Hung 491291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_index_array(dst, dst_channels, src, src_channels, idxary, sample_size, count); 492291a1948093850aa87f60264680404b2b96ee327Andy Hung} 493291a1948093850aa87f60264680404b2b96ee327Andy Hung 494291a1948093850aa87f60264680404b2b96ee327Andy Hung// a modified version of the memcpy_by_channel_mask test 495291a1948093850aa87f60264680404b2b96ee327Andy Hung// but using 24 bit type and memcpy_by_index_array() 496291a1948093850aa87f60264680404b2b96ee327Andy HungTEST(audio_utils_primitives, memcpy_by_index_array_dst_index) { 497291a1948093850aa87f60264680404b2b96ee327Andy Hung uint32_t dst_mask; 498291a1948093850aa87f60264680404b2b96ee327Andy Hung uint32_t src_mask; 499291a1948093850aa87f60264680404b2b96ee327Andy Hung typedef struct {uint8_t c[3];} __attribute__((__packed__)) uint8x3_t; 500291a1948093850aa87f60264680404b2b96ee327Andy Hung uint8x3_t *u24ref = new uint8x3_t[65536]; 501291a1948093850aa87f60264680404b2b96ee327Andy Hung uint8x3_t *u24ary = new uint8x3_t[65536]; 502291a1948093850aa87f60264680404b2b96ee327Andy Hung uint16_t *u16ref = new uint16_t[65536]; 503291a1948093850aa87f60264680404b2b96ee327Andy Hung uint16_t *u16ary = new uint16_t[65536]; 504291a1948093850aa87f60264680404b2b96ee327Andy Hung 505291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ((size_t)3, sizeof(uint8x3_t)); // 3 bytes per struct 506291a1948093850aa87f60264680404b2b96ee327Andy Hung 507291a1948093850aa87f60264680404b2b96ee327Andy Hung // tests prepare_index_array_from_masks() 508291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ((size_t)4, memcpy_by_index_array_initialization_dst_index(NULL, 0, 0x8d, 0x8c)); 509291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ((size_t)3, memcpy_by_index_array_initialization_dst_index(NULL, 0, 0x8c, 0x8d)); 510291a1948093850aa87f60264680404b2b96ee327Andy Hung 511291a1948093850aa87f60264680404b2b96ee327Andy Hung for (size_t i = 0; i < 65536; ++i) { 512291a1948093850aa87f60264680404b2b96ee327Andy Hung u16ref[i] = i; 513291a1948093850aa87f60264680404b2b96ee327Andy Hung } 514291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_to_p24_from_i16((uint8_t*)u24ref, (int16_t*)u16ref, 65536); 515291a1948093850aa87f60264680404b2b96ee327Andy Hung 516291a1948093850aa87f60264680404b2b96ee327Andy Hung // Test when src mask is 0. Everything copied is zero. 517291a1948093850aa87f60264680404b2b96ee327Andy Hung src_mask = 0; 518291a1948093850aa87f60264680404b2b96ee327Andy Hung dst_mask = 0x8d; 519291a1948093850aa87f60264680404b2b96ee327Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 520291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_channel_mask_dst_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 521291a1948093850aa87f60264680404b2b96ee327Andy Hung 65536 / popcount(dst_mask)); 522291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 523291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 524291a1948093850aa87f60264680404b2b96ee327Andy Hung 525291a1948093850aa87f60264680404b2b96ee327Andy Hung // Test when dst_mask is 0. Nothing should be copied. 526291a1948093850aa87f60264680404b2b96ee327Andy Hung src_mask = 0; 527291a1948093850aa87f60264680404b2b96ee327Andy Hung dst_mask = 0; 528291a1948093850aa87f60264680404b2b96ee327Andy Hung memset(u24ary, 0, 65536 * sizeof(u24ary[0])); 529291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_channel_mask_dst_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 530291a1948093850aa87f60264680404b2b96ee327Andy Hung 65536); 531291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 532291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 533291a1948093850aa87f60264680404b2b96ee327Andy Hung 534291a1948093850aa87f60264680404b2b96ee327Andy Hung // Test when dst mask equals source count size. One to one copy. 535291a1948093850aa87f60264680404b2b96ee327Andy Hung src_mask = 0x8d; 536291a1948093850aa87f60264680404b2b96ee327Andy Hung dst_mask = 0x0f; 537291a1948093850aa87f60264680404b2b96ee327Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 538291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_channel_mask_dst_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 555); 539291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ(0, memcmp(u24ary, u24ref, 555 * sizeof(u24ref[0]) * popcount(dst_mask))); 540291a1948093850aa87f60264680404b2b96ee327Andy Hung 541291a1948093850aa87f60264680404b2b96ee327Andy Hung // Test with a gap in source: 542291a1948093850aa87f60264680404b2b96ee327Andy Hung // Input 3 samples, output 4 samples, one zero inserted. 543291a1948093850aa87f60264680404b2b96ee327Andy Hung src_mask = 0x8c; 544291a1948093850aa87f60264680404b2b96ee327Andy Hung dst_mask = 0x0f; 545291a1948093850aa87f60264680404b2b96ee327Andy Hung memset(u24ary, 0x9, 65536 * sizeof(u24ary[0])); 546291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_channel_mask_dst_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 547291a1948093850aa87f60264680404b2b96ee327Andy Hung 65536 / popcount(dst_mask)); 548291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 549291a1948093850aa87f60264680404b2b96ee327Andy Hung checkMonotoneOrZero(u16ary, 65536); 550291a1948093850aa87f60264680404b2b96ee327Andy Hung EXPECT_EQ((size_t)(65536 * 3 / 4 - 1), nonZeroMono16((int16_t*)u16ary, 65536)); 551291a1948093850aa87f60264680404b2b96ee327Andy Hung 552291a1948093850aa87f60264680404b2b96ee327Andy Hung // Test with a gap in destination: 553291a1948093850aa87f60264680404b2b96ee327Andy Hung // Input 4 samples, output 3 samples, one deleted 554291a1948093850aa87f60264680404b2b96ee327Andy Hung src_mask = 0x8d; 555291a1948093850aa87f60264680404b2b96ee327Andy Hung dst_mask = 0x07; 556291a1948093850aa87f60264680404b2b96ee327Andy Hung memset(u24ary, 0x9, 65536 * sizeof(u24ary[0])); 557291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_by_channel_mask_dst_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 558291a1948093850aa87f60264680404b2b96ee327Andy Hung 65536 / popcount(src_mask)); 559291a1948093850aa87f60264680404b2b96ee327Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 560291a1948093850aa87f60264680404b2b96ee327Andy Hung checkMonotone(u16ary, 65536 * 3 / 4); 5613af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 5623af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung delete[] u16ref; 5633af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung delete[] u16ary; 5643af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung delete[] u24ref; 5653af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung delete[] u24ary; 5663af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung} 567e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 5685a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hungvoid memcpy_by_channel_mask_src_index(void *dst, uint32_t dst_mask, 5695a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung const void *src, uint32_t src_mask, size_t sample_size, size_t count) 5705a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung{ 5715a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung int8_t idxary[32]; 5725a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint32_t src_channels = popcount(src_mask); 5735a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint32_t dst_channels = 5745a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_index_array_initialization_src_index(idxary, 32, dst_mask, src_mask); 5755a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 5765a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_index_array(dst, dst_channels, src, src_channels, idxary, sample_size, count); 5775a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung} 5785a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 5795a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung// a modified version of the memcpy_by_channel_mask test 5805a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung// but using 24 bit type and memcpy_by_index_array() 5815a0d0285cdd75cd5c94e020311830d634d6587b0Andy HungTEST(audio_utils_primitives, memcpy_by_index_array_src_index) { 5825a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint32_t dst_mask; 5835a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint32_t src_mask; 5845a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung typedef struct {uint8_t c[3];} __attribute__((__packed__)) uint8x3_t; 5855a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint8x3_t *u24ref = new uint8x3_t[65536]; 5865a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint8x3_t *u24ary = new uint8x3_t[65536]; 5875a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint16_t *u16ref = new uint16_t[65536]; 5885a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint16_t *u16ary = new uint16_t[65536]; 5895a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 5905a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ((size_t)3, sizeof(uint8x3_t)); // 3 bytes per struct 5915a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 5925a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // tests prepare_index_array_from_masks() 5935a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ((size_t)4, memcpy_by_index_array_initialization_src_index(NULL, 0, 0x8d, 0x8c)); 5945a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ((size_t)3, memcpy_by_index_array_initialization_src_index(NULL, 0, 0x8c, 0x8d)); 5955a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 5965a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung for (size_t i = 0; i < 65536; ++i) { 5975a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung u16ref[i] = i; 5985a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung } 5995a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_to_p24_from_i16((uint8_t*)u24ref, (int16_t*)u16ref, 65536); 6005a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6015a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Test when src mask is 0. Everything copied is zero. 6025a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung src_mask = 0; 6035a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung dst_mask = 0x8d; 6045a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 6055a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_channel_mask_src_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 6065a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 65536 / popcount(dst_mask)); 6075a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 6085a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 6095a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6105a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Test when dst_mask is 0. Nothing should be copied. 6115a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung src_mask = 0; 6125a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung dst_mask = 0; 6135a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memset(u24ary, 0, 65536 * sizeof(u24ary[0])); 6145a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_channel_mask_src_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 6155a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 65536); 6165a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 6175a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ((size_t)0, nonZeroMono16((int16_t*)u16ary, 65530)); 6185a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6195a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Test when source mask must copy to dst mask. One to one copy. 6205a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung src_mask = 0xf; 6215a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung dst_mask = 0xf; 6225a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 6235a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_channel_mask_src_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 555); 6245a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ(0, memcmp(u24ary, u24ref, 555 * sizeof(u24ref[0]) * popcount(dst_mask))); 6255a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6265a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Test when source mask must copy to dst mask. One to one copy. 6275a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung src_mask = 0xf; 6285a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung dst_mask = 0x8d; 6295a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memset(u24ary, 0x99, 65536 * sizeof(u24ary[0])); 6305a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_channel_mask_src_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 555); 6315a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ(0, memcmp(u24ary, u24ref, 555 * sizeof(u24ref[0]) * popcount(dst_mask))); 6325a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6335a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Test with a gap in source: 6345a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Input 3 samples, output 4 samples, one zero inserted. 6355a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung src_mask = 0x07; 6365a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung dst_mask = 0x8d; 6375a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memset(u24ary, 0x9, 65536 * sizeof(u24ary[0])); 6385a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_channel_mask_src_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 6395a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 65536 / popcount(dst_mask)); 6405a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 6415a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung checkMonotoneOrZero(u16ary, 65536); 6425a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung EXPECT_EQ((size_t)(65536 * 3 / 4 - 1), nonZeroMono16((int16_t*)u16ary, 65536)); 6435a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6445a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Test with a gap in destination: 6455a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung // Input 4 samples, output 3 samples, one deleted 6465a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung src_mask = 0x0f; 6475a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung dst_mask = 0x8c; 6485a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memset(u24ary, 0x9, 65536 * sizeof(u24ary[0])); 6495a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_by_channel_mask_src_index(u24ary, dst_mask, u24ref, src_mask, sizeof(u24ref[0]), 6505a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 65536 / popcount(src_mask)); 6515a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung memcpy_to_i16_from_p24((int16_t*)u16ary, (uint8_t*)u24ary, 65536); 6525a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung checkMonotone(u16ary, 65536 * 3 / 4); 6535a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 6545a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung delete[] u16ref; 6555a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung delete[] u16ary; 6565a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung delete[] u24ref; 6575a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung delete[] u24ary; 6585a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung} 6595a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 660e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy HungTEST(audio_utils_channels, adjust_channels) { 661e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung uint16_t *u16ref = new uint16_t[65536]; 662e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung uint16_t *u16expand = new uint16_t[65536*2]; 663e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung uint16_t *u16ary = new uint16_t[65536]; 664e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 665e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung // reference buffer always increases 666e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung for (size_t i = 0; i < 65536; ++i) { 667e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung u16ref[i] = i; 668e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung } 669e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 670e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung // expand channels from stereo to quad. 671e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung adjust_channels(u16ref /*in_buff*/, 2 /*in_channels*/, 672e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung u16expand /*out_buff*/, 4 /*out_channels*/, 673e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung sizeof(u16ref[0]) /*sample_size_in_bytes*/, 674e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung sizeof(u16ref[0])*65536 /*num_in_bytes*/); 675e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 676e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung // expanded buffer must increase (or be zero) 677e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung checkMonotoneOrZero(u16expand, 65536*2); 678e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 679e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung // contract channels back to stereo. 680e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung adjust_channels(u16expand /*in_buff*/, 4 /*in_channels*/, 681e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung u16ary /*out_buff*/, 2 /*out_channels*/, 682e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung sizeof(u16expand[0]) /*sample_size_in_bytes*/, 683e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung sizeof(u16expand[0])*65536*2 /*num_in_bytes*/); 684e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 685e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung // must be identical to original. 686bbc7281af9719774ea310fbeff3830f3aadd5edeAndy Hung EXPECT_EQ(0, memcmp(u16ary, u16ref, sizeof(u16ref[0])*65536)); 687e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung 688e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung delete[] u16ref; 689e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung delete[] u16expand; 690e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung delete[] u16ary; 691e0ccb20d0b3ab5c686508a7b1413928320ec2d1fAndy Hung} 692