1fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung/* 2fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * Copyright (C) 2014 The Android Open Source Project 3fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * 4fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * Licensed under the Apache License, Version 2.0 (the "License"); 5fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * you may not use this file except in compliance with the License. 6fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * You may obtain a copy of the License at 7fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * 8fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * http://www.apache.org/licenses/LICENSE-2.0 9fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * 10fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * Unless required by applicable law or agreed to in writing, software 11fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * distributed under the License is distributed on an "AS IS" BASIS, 12fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * See the License for the specific language governing permissions and 14fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung * limitations under the License. 15fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung */ 16fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung 17e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung/* #define LOG_NDEBUG 0 */ 18fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung#define LOG_TAG "audio_utils_format" 19fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung 20fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung#include <cutils/log.h> 21fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung#include <audio_utils/primitives.h> 22fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung#include <audio_utils/format.h> 23fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung 24fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hungvoid memcpy_by_audio_format(void *dst, audio_format_t dst_format, 251bc2b26d07a8510a7c08f222765648305b91e829Andy Hung const void *src, audio_format_t src_format, size_t count) 26e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung{ 27e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung /* default cases for error falls through to fatal log below. */ 28e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung if (dst_format == src_format) { 29e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung switch (dst_format) { 30e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_16_BIT: 31e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_FLOAT: 3223ef1b379caa5e641367f115d67080ed35069117Andy Hung case AUDIO_FORMAT_PCM_8_BIT: 33e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_24_BIT_PACKED: 34e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_32_BIT: 35e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_8_24_BIT: 36e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy(dst, src, count * audio_bytes_per_sample(dst_format)); 37e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 38e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung default: 39e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung break; 40e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung } 41fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung } 42fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung switch (dst_format) { 43fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_16_BIT: 44fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung switch (src_format) { 45fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_FLOAT: 46fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung memcpy_to_i16_from_float((int16_t*)dst, (float*)src, count); 47fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung return; 4823ef1b379caa5e641367f115d67080ed35069117Andy Hung case AUDIO_FORMAT_PCM_8_BIT: 4923ef1b379caa5e641367f115d67080ed35069117Andy Hung memcpy_to_i16_from_u8((int16_t*)dst, (uint8_t*)src, count); 5023ef1b379caa5e641367f115d67080ed35069117Andy Hung return; 51fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_24_BIT_PACKED: 52fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung memcpy_to_i16_from_p24((int16_t*)dst, (uint8_t*)src, count); 53fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung return; 54e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_32_BIT: 55e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_i16_from_i32((int16_t*)dst, (int32_t*)src, count); 56e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 57e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_8_24_BIT: 58e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_i16_from_q8_23((int16_t*)dst, (int32_t*)src, count); 59e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 60fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung default: 61fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 62fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung } 63fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 64fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_FLOAT: 65fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung switch (src_format) { 66fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_16_BIT: 67fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung memcpy_to_float_from_i16((float*)dst, (int16_t*)src, count); 68fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung return; 6923ef1b379caa5e641367f115d67080ed35069117Andy Hung case AUDIO_FORMAT_PCM_8_BIT: 7023ef1b379caa5e641367f115d67080ed35069117Andy Hung memcpy_to_float_from_u8((float*)dst, (uint8_t*)src, count); 7123ef1b379caa5e641367f115d67080ed35069117Andy Hung return; 72fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_24_BIT_PACKED: 73fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung memcpy_to_float_from_p24((float*)dst, (uint8_t*)src, count); 74fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung return; 75e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_32_BIT: 76e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_float_from_i32((float*)dst, (int32_t*)src, count); 77e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 78e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_8_24_BIT: 79e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_float_from_q8_23((float*)dst, (int32_t*)src, count); 80e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 81fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung default: 82fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 83fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung } 84fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 8523ef1b379caa5e641367f115d67080ed35069117Andy Hung case AUDIO_FORMAT_PCM_8_BIT: 8623ef1b379caa5e641367f115d67080ed35069117Andy Hung switch (src_format) { 8723ef1b379caa5e641367f115d67080ed35069117Andy Hung case AUDIO_FORMAT_PCM_16_BIT: 8823ef1b379caa5e641367f115d67080ed35069117Andy Hung memcpy_to_u8_from_i16((uint8_t*)dst, (int16_t*)src, count); 8923ef1b379caa5e641367f115d67080ed35069117Andy Hung return; 9023ef1b379caa5e641367f115d67080ed35069117Andy Hung case AUDIO_FORMAT_PCM_FLOAT: 9123ef1b379caa5e641367f115d67080ed35069117Andy Hung memcpy_to_u8_from_float((uint8_t*)dst, (float*)src, count); 9223ef1b379caa5e641367f115d67080ed35069117Andy Hung return; 9323ef1b379caa5e641367f115d67080ed35069117Andy Hung default: 9423ef1b379caa5e641367f115d67080ed35069117Andy Hung break; 9523ef1b379caa5e641367f115d67080ed35069117Andy Hung } 9623ef1b379caa5e641367f115d67080ed35069117Andy Hung break; 97fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_24_BIT_PACKED: 98fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung switch (src_format) { 99fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_16_BIT: 100fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung memcpy_to_p24_from_i16((uint8_t*)dst, (int16_t*)src, count); 101fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung return; 102fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung case AUDIO_FORMAT_PCM_FLOAT: 103fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung memcpy_to_p24_from_float((uint8_t*)dst, (float*)src, count); 104fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung return; 105bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George case AUDIO_FORMAT_PCM_32_BIT: 106bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_p24_from_i32((uint8_t*)dst, (int32_t*)src, count); 107bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George return; 108bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George case AUDIO_FORMAT_PCM_8_24_BIT: 109bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_p24_from_q8_23((uint8_t*)dst, (int32_t*)src, count); 110bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George return; 111fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung default: 112fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 113fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung } 114fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 115e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_32_BIT: 116e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung switch (src_format) { 117e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_16_BIT: 118e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_i32_from_i16((int32_t*)dst, (int16_t*)src, count); 119e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 120e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_FLOAT: 121e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count); 122e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 123bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George case AUDIO_FORMAT_PCM_24_BIT_PACKED: 124bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George memcpy_to_i32_from_p24((int32_t*)dst, (uint8_t *)src, count); 125bad0898a944d6a7886b4ab8ca8e0157885d9aadfHaynes Mathew George return; 126e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung default: 127e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung break; 128e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung } 129e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung break; 130e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_8_24_BIT: 131e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung switch (src_format) { 132e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_16_BIT: 133e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_q8_23_from_i16((int32_t*)dst, (int16_t*)src, count); 134e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 135e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung case AUDIO_FORMAT_PCM_FLOAT: 136e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung memcpy_to_q8_23_from_float_with_clamp((int32_t*)dst, (float*)src, count); 137e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung return; 13878ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George case AUDIO_FORMAT_PCM_24_BIT_PACKED: { 13978ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George memcpy_to_q8_23_from_p24((int32_t *)dst, (uint8_t *)src, count); 14078ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George return; 14178ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George } 142e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung default: 143e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung break; 144e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung } 145e46f5534fa219a760822c8b08bc81a3267b5ff2bAndy Hung break; 146fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung default: 147fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung break; 148fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung } 149fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung LOG_ALWAYS_FATAL("invalid src format %#x for dst format %#x", 150fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung src_format, dst_format); 151fcad7e469959f3a8f0a3060ca3d74f72fea39efaAndy Hung} 152b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung 153b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hungsize_t memcpy_by_index_array_initialization_from_channel_mask(int8_t *idxary, size_t arysize, 154b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung audio_channel_mask_t dst_channel_mask, audio_channel_mask_t src_channel_mask) 155b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung{ 156b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung const audio_channel_representation_t src_representation = 157b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung audio_channel_mask_get_representation(src_channel_mask); 158b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung const audio_channel_representation_t dst_representation = 159b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung audio_channel_mask_get_representation(dst_channel_mask); 160b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung const uint32_t src_bits = audio_channel_mask_get_bits(src_channel_mask); 161b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung const uint32_t dst_bits = audio_channel_mask_get_bits(dst_channel_mask); 162b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung 163b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung switch (src_representation) { 164b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung case AUDIO_CHANNEL_REPRESENTATION_POSITION: 165b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung switch (dst_representation) { 166b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung case AUDIO_CHANNEL_REPRESENTATION_POSITION: 167b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return memcpy_by_index_array_initialization(idxary, arysize, 168b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung dst_bits, src_bits); 169b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung case AUDIO_CHANNEL_REPRESENTATION_INDEX: 170b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return memcpy_by_index_array_initialization_dst_index(idxary, arysize, 171b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung dst_bits, src_bits); 172b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung default: 173b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return 0; 174b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung } 175b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung break; 176b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung case AUDIO_CHANNEL_REPRESENTATION_INDEX: 177b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung switch (dst_representation) { 178b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung case AUDIO_CHANNEL_REPRESENTATION_POSITION: 179b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return memcpy_by_index_array_initialization_src_index(idxary, arysize, 180b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung dst_bits, src_bits); 181b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung case AUDIO_CHANNEL_REPRESENTATION_INDEX: 182b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return memcpy_by_index_array_initialization(idxary, arysize, 183b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung dst_bits, src_bits); 184b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung default: 185b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return 0; 186b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung } 187b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung break; 188b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung default: 189b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung return 0; 190b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung } 191b2eefeab3431f293d5dfe5e27e180f2359bb47f1Andy Hung} 192