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