status_t AudioConverter::safeConvert(const sp<MediaCodecBuffer> &src, sp<MediaCodecBuffer> &tgt) { if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcm16bit) { memcpy_to_u8_from_i16((uint8_t*)tgt->base(), (const int16_t*)src->data(), src->size() / 2); } else if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcmFloat) { memcpy_to_u8_from_float((uint8_t*)tgt->base(), (const float*)src->data(), src->size() / 4); } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcm8bit) { memcpy_to_i16_from_u8((int16_t*)tgt->base(), (const uint8_t*)src->data(), src->size()); } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcmFloat) { memcpy_to_i16_from_float((int16_t*)tgt->base(), (const float*)src->data(), src->size() / 4); } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm8bit) { memcpy_to_float_from_u8((float*)tgt->base(), (const uint8_t*)src->data(), src->size()); } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm16bit) { memcpy_to_float_from_i16((float*)tgt->base(), (const int16_t*)src->data(), src->size() / 2); } else { return INVALID_OPERATION; } return OK; }
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); }