TEST(audio_utils_primitives, memcpy) { // test round-trip. int16_t *i16ref = new int16_t[65536]; int16_t *i16ary = new int16_t[65536]; int32_t *i32ary = new int32_t[65536]; float *fary = new float[65536]; uint8_t *pary = new uint8_t[65536*3]; for (size_t i = 0; i < 65536; ++i) { i16ref[i] = i16ary[i] = i - 32768; } // do round-trip testing i16 and float memcpy_to_float_from_i16(fary, i16ary, 65536); memset(i16ary, 0, 65536 * sizeof(i16ary[0])); checkMonotone(fary, 65536); memcpy_to_i16_from_float(i16ary, fary, 65536); memset(fary, 0, 65536 * sizeof(fary[0])); checkMonotone(i16ary, 65536); // TODO make a template case for the following? // do round-trip testing p24 to i16 and float memcpy_to_p24_from_i16(pary, i16ary, 65536); memset(i16ary, 0, 65536 * sizeof(i16ary[0])); // check an intermediate format at a position(???) #if 0 printf("pary[%d].0 = %u pary[%d].1 = %u pary[%d].2 = %u\n", 1025, (unsigned) pary[1025*3], 1025, (unsigned) pary[1025*3+1], 1025, (unsigned) pary[1025*3+2] ); #endif memcpy_to_float_from_p24(fary, pary, 65536); memset(pary, 0, 65536 * 3 * sizeof(pary[0])); checkMonotone(fary, 65536); memcpy_to_p24_from_float(pary, fary, 65536); memset(fary, 0, 65536 * sizeof(fary[0])); memcpy_to_i16_from_p24(i16ary, pary, 65536); memset(pary, 0, 65536 * 3 * sizeof(pary[0])); checkMonotone(i16ary, 65536); // do round-trip testing q8_23 to i16 and float memcpy_to_q8_23_from_i16(i32ary, i16ary, 65536); memset(i16ary, 0, 65536 * sizeof(i16ary[0])); checkMonotone(i32ary, 65536); memcpy_to_float_from_q8_23(fary, i32ary, 65536); memset(i32ary, 0, 65536 * sizeof(i32ary[0])); checkMonotone(fary, 65536); memcpy_to_q8_23_from_float_with_clamp(i32ary, fary, 65536); memset(fary, 0, 65536 * sizeof(fary[0])); checkMonotone(i32ary, 65536); memcpy_to_i16_from_q8_23(i16ary, i32ary, 65536); memset(i32ary, 0, 65536 * sizeof(i32ary[0])); checkMonotone(i16ary, 65536); // do round-trip testing i32 to i16 and float memcpy_to_i32_from_i16(i32ary, i16ary, 65536); memset(i16ary, 0, 65536 * sizeof(i16ary[0])); checkMonotone(i32ary, 65536); memcpy_to_float_from_i32(fary, i32ary, 65536); memset(i32ary, 0, 65536 * sizeof(i32ary[0])); checkMonotone(fary, 65536); memcpy_to_i32_from_float(i32ary, fary, 65536); memset(fary, 0, 65536 * sizeof(fary[0])); checkMonotone(i32ary, 65536); memcpy_to_i16_from_i32(i16ary, i32ary, 65536); memset(i32ary, 0, 65536 * sizeof(i32ary[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 memcpy_to_q4_27_from_float(i32ary, fary, 65536); memset(fary, 0, 65536 * sizeof(fary[0])); checkMonotone(i32ary, 65536); memcpy_to_float_from_q4_27(fary, i32ary, 65536); memset(i32ary, 0, 65536 * sizeof(i32ary[0])); checkMonotone(fary, 65536); // at the end, our i16ary must be the same. (Monotone should be equivalent to this) EXPECT_EQ(memcmp(i16ary, i16ref, 65536*sizeof(i16ary[0])), 0); delete[] i16ref; delete[] i16ary; delete[] i32ary; delete[] fary; delete[] pary; }
void memcpy_by_audio_format(void *dst, audio_format_t dst_format, const void *src, audio_format_t src_format, size_t count) { /* default cases for error falls through to fatal log below. */ if (dst_format == src_format) { switch (dst_format) { case AUDIO_FORMAT_PCM_16_BIT: case AUDIO_FORMAT_PCM_FLOAT: case AUDIO_FORMAT_PCM_8_BIT: case AUDIO_FORMAT_PCM_24_BIT_PACKED: case AUDIO_FORMAT_PCM_32_BIT: case AUDIO_FORMAT_PCM_8_24_BIT: memcpy(dst, src, count * audio_bytes_per_sample(dst_format)); return; default: break; } } switch (dst_format) { case AUDIO_FORMAT_PCM_16_BIT: switch (src_format) { case AUDIO_FORMAT_PCM_FLOAT: memcpy_to_i16_from_float((int16_t*)dst, (float*)src, count); return; case AUDIO_FORMAT_PCM_8_BIT: memcpy_to_i16_from_u8((int16_t*)dst, (uint8_t*)src, count); return; case AUDIO_FORMAT_PCM_24_BIT_PACKED: memcpy_to_i16_from_p24((int16_t*)dst, (uint8_t*)src, count); return; case AUDIO_FORMAT_PCM_32_BIT: memcpy_to_i16_from_i32((int16_t*)dst, (int32_t*)src, count); return; case AUDIO_FORMAT_PCM_8_24_BIT: memcpy_to_i16_from_q8_23((int16_t*)dst, (int32_t*)src, count); return; default: break; } break; case AUDIO_FORMAT_PCM_FLOAT: switch (src_format) { case AUDIO_FORMAT_PCM_16_BIT: memcpy_to_float_from_i16((float*)dst, (int16_t*)src, count); return; case AUDIO_FORMAT_PCM_8_BIT: memcpy_to_float_from_u8((float*)dst, (uint8_t*)src, count); return; case AUDIO_FORMAT_PCM_24_BIT_PACKED: memcpy_to_float_from_p24((float*)dst, (uint8_t*)src, count); return; case AUDIO_FORMAT_PCM_32_BIT: memcpy_to_float_from_i32((float*)dst, (int32_t*)src, count); return; case AUDIO_FORMAT_PCM_8_24_BIT: memcpy_to_float_from_q8_23((float*)dst, (int32_t*)src, count); return; default: break; } break; case AUDIO_FORMAT_PCM_8_BIT: switch (src_format) { case AUDIO_FORMAT_PCM_16_BIT: memcpy_to_u8_from_i16((uint8_t*)dst, (int16_t*)src, count); return; case AUDIO_FORMAT_PCM_FLOAT: memcpy_to_u8_from_float((uint8_t*)dst, (float*)src, count); return; default: break; } break; case AUDIO_FORMAT_PCM_24_BIT_PACKED: switch (src_format) { case AUDIO_FORMAT_PCM_16_BIT: memcpy_to_p24_from_i16((uint8_t*)dst, (int16_t*)src, count); return; case AUDIO_FORMAT_PCM_FLOAT: memcpy_to_p24_from_float((uint8_t*)dst, (float*)src, count); return; default: break; } break; case AUDIO_FORMAT_PCM_32_BIT: switch (src_format) { case AUDIO_FORMAT_PCM_16_BIT: memcpy_to_i32_from_i16((int32_t*)dst, (int16_t*)src, count); return; case AUDIO_FORMAT_PCM_FLOAT: memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count); return; default: break; } break; case AUDIO_FORMAT_PCM_8_24_BIT: switch (src_format) { case AUDIO_FORMAT_PCM_16_BIT: memcpy_to_q8_23_from_i16((int32_t*)dst, (int16_t*)src, count); return; case AUDIO_FORMAT_PCM_FLOAT: memcpy_to_q8_23_from_float_with_clamp((int32_t*)dst, (float*)src, count); return; case AUDIO_FORMAT_PCM_24_BIT_PACKED: { memcpy_to_q8_23_from_p24((int32_t *)dst, (uint8_t *)src, count); return; } default: break; } break; default: break; } LOG_ALWAYS_FATAL("invalid src format %#x for dst format %#x", src_format, dst_format); }