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