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 #include <assert.h> 18 #include <audio_utils/format.h> 19 #include <audio_utils/primitives.h> 20 21 void memcpy_by_audio_format(void *dst, audio_format_t dst_format, 22 const void *src, audio_format_t src_format, size_t count) 23 { 24 /* default cases for error falls through to assert(false) below. */ 25 if (dst_format == src_format) { 26 switch (dst_format) { 27 case AUDIO_FORMAT_PCM_16_BIT: 28 case AUDIO_FORMAT_PCM_FLOAT: 29 case AUDIO_FORMAT_PCM_8_BIT: 30 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 31 case AUDIO_FORMAT_PCM_32_BIT: 32 case AUDIO_FORMAT_PCM_8_24_BIT: 33 if (dst != src) { 34 // TODO: should assert if memory regions overlap. 35 memcpy(dst, src, count * audio_bytes_per_sample(dst_format)); 36 } 37 return; 38 default: 39 break; 40 } 41 } 42 switch (dst_format) { 43 case AUDIO_FORMAT_PCM_16_BIT: 44 switch (src_format) { 45 case AUDIO_FORMAT_PCM_FLOAT: 46 memcpy_to_i16_from_float((int16_t*)dst, (float*)src, count); 47 return; 48 case AUDIO_FORMAT_PCM_8_BIT: 49 memcpy_to_i16_from_u8((int16_t*)dst, (uint8_t*)src, count); 50 return; 51 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 52 memcpy_to_i16_from_p24((int16_t*)dst, (uint8_t*)src, count); 53 return; 54 case AUDIO_FORMAT_PCM_32_BIT: 55 memcpy_to_i16_from_i32((int16_t*)dst, (int32_t*)src, count); 56 return; 57 case AUDIO_FORMAT_PCM_8_24_BIT: 58 memcpy_to_i16_from_q8_23((int16_t*)dst, (int32_t*)src, count); 59 return; 60 default: 61 break; 62 } 63 break; 64 case AUDIO_FORMAT_PCM_FLOAT: 65 switch (src_format) { 66 case AUDIO_FORMAT_PCM_16_BIT: 67 memcpy_to_float_from_i16((float*)dst, (int16_t*)src, count); 68 return; 69 case AUDIO_FORMAT_PCM_8_BIT: 70 memcpy_to_float_from_u8((float*)dst, (uint8_t*)src, count); 71 return; 72 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 73 memcpy_to_float_from_p24((float*)dst, (uint8_t*)src, count); 74 return; 75 case AUDIO_FORMAT_PCM_32_BIT: 76 memcpy_to_float_from_i32((float*)dst, (int32_t*)src, count); 77 return; 78 case AUDIO_FORMAT_PCM_8_24_BIT: 79 memcpy_to_float_from_q8_23((float*)dst, (int32_t*)src, count); 80 return; 81 default: 82 break; 83 } 84 break; 85 case AUDIO_FORMAT_PCM_8_BIT: 86 switch (src_format) { 87 case AUDIO_FORMAT_PCM_16_BIT: 88 memcpy_to_u8_from_i16((uint8_t*)dst, (int16_t*)src, count); 89 return; 90 case AUDIO_FORMAT_PCM_FLOAT: 91 memcpy_to_u8_from_float((uint8_t*)dst, (float*)src, count); 92 return; 93 // The following converts HAL to AudioRecord formats. 94 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 95 memcpy_to_u8_from_p24((uint8_t*)dst, (uint8_t*)src, count); 96 return; 97 case AUDIO_FORMAT_PCM_32_BIT: 98 memcpy_to_u8_from_i32((uint8_t*)dst, (int32_t*)src, count); 99 return; 100 case AUDIO_FORMAT_PCM_8_24_BIT: 101 memcpy_to_u8_from_q8_23((uint8_t*)dst, (int32_t*)src, count); 102 return; 103 default: 104 break; 105 } 106 break; 107 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 108 switch (src_format) { 109 case AUDIO_FORMAT_PCM_16_BIT: 110 memcpy_to_p24_from_i16((uint8_t*)dst, (int16_t*)src, count); 111 return; 112 case AUDIO_FORMAT_PCM_FLOAT: 113 memcpy_to_p24_from_float((uint8_t*)dst, (float*)src, count); 114 return; 115 case AUDIO_FORMAT_PCM_32_BIT: 116 memcpy_to_p24_from_i32((uint8_t*)dst, (int32_t*)src, count); 117 return; 118 case AUDIO_FORMAT_PCM_8_24_BIT: 119 memcpy_to_p24_from_q8_23((uint8_t*)dst, (int32_t*)src, count); 120 return; 121 default: 122 break; 123 } 124 break; 125 case AUDIO_FORMAT_PCM_32_BIT: 126 switch (src_format) { 127 case AUDIO_FORMAT_PCM_16_BIT: 128 memcpy_to_i32_from_i16((int32_t*)dst, (int16_t*)src, count); 129 return; 130 case AUDIO_FORMAT_PCM_FLOAT: 131 memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count); 132 return; 133 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 134 memcpy_to_i32_from_p24((int32_t*)dst, (uint8_t *)src, count); 135 return; 136 default: 137 break; 138 } 139 break; 140 case AUDIO_FORMAT_PCM_8_24_BIT: 141 switch (src_format) { 142 case AUDIO_FORMAT_PCM_16_BIT: 143 memcpy_to_q8_23_from_i16((int32_t*)dst, (int16_t*)src, count); 144 return; 145 case AUDIO_FORMAT_PCM_FLOAT: 146 memcpy_to_q8_23_from_float_with_clamp((int32_t*)dst, (float*)src, count); 147 return; 148 case AUDIO_FORMAT_PCM_24_BIT_PACKED: { 149 memcpy_to_q8_23_from_p24((int32_t *)dst, (uint8_t *)src, count); 150 return; 151 } 152 default: 153 break; 154 } 155 break; 156 default: 157 break; 158 } 159 // invalid src format for dst format 160 assert(false); 161 } 162 163 size_t memcpy_by_index_array_initialization_from_channel_mask(int8_t *idxary, size_t arysize, 164 audio_channel_mask_t dst_channel_mask, audio_channel_mask_t src_channel_mask) 165 { 166 const audio_channel_representation_t src_representation = 167 audio_channel_mask_get_representation(src_channel_mask); 168 const audio_channel_representation_t dst_representation = 169 audio_channel_mask_get_representation(dst_channel_mask); 170 const uint32_t src_bits = audio_channel_mask_get_bits(src_channel_mask); 171 const uint32_t dst_bits = audio_channel_mask_get_bits(dst_channel_mask); 172 173 switch (src_representation) { 174 case AUDIO_CHANNEL_REPRESENTATION_POSITION: 175 switch (dst_representation) { 176 case AUDIO_CHANNEL_REPRESENTATION_POSITION: 177 return memcpy_by_index_array_initialization(idxary, arysize, 178 dst_bits, src_bits); 179 case AUDIO_CHANNEL_REPRESENTATION_INDEX: 180 return memcpy_by_index_array_initialization_dst_index(idxary, arysize, 181 dst_bits, src_bits); 182 default: 183 return 0; 184 } 185 break; 186 case AUDIO_CHANNEL_REPRESENTATION_INDEX: 187 switch (dst_representation) { 188 case AUDIO_CHANNEL_REPRESENTATION_POSITION: 189 return memcpy_by_index_array_initialization_src_index(idxary, arysize, 190 dst_bits, src_bits); 191 case AUDIO_CHANNEL_REPRESENTATION_INDEX: 192 return memcpy_by_index_array_initialization(idxary, arysize, 193 dst_bits, src_bits); 194 default: 195 return 0; 196 } 197 break; 198 default: 199 return 0; 200 } 201 } 202 203 void accumulate_by_audio_format(void *dst, const void *src, 204 audio_format_t format, size_t count) { 205 switch (format) { 206 case AUDIO_FORMAT_PCM_16_BIT: 207 accumulate_i16((int16_t *)dst, (const int16_t *)src, count); 208 return; 209 case AUDIO_FORMAT_PCM_FLOAT: 210 accumulate_float((float *)dst, (const float *)src, count); 211 return; 212 case AUDIO_FORMAT_PCM_8_BIT: 213 accumulate_u8((uint8_t *)dst, (const uint8_t *)src, count); 214 return; 215 case AUDIO_FORMAT_PCM_24_BIT_PACKED: 216 accumulate_p24((uint8_t *)dst, (const uint8_t *)src, count); 217 return; 218 case AUDIO_FORMAT_PCM_32_BIT: 219 accumulate_i32((int32_t *)dst, (const int32_t *)src, count); 220 return; 221 case AUDIO_FORMAT_PCM_8_24_BIT: 222 accumulate_q8_23((int32_t *)dst, (const int32_t *)src, count); 223 return; 224 default: 225 break; 226 } 227 // invalid format 228 assert(false); 229 } 230