OSDN Git Service

audio_utils: Support more format conversions
[android-x86/system-media.git] / audio_utils / format.c
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 <cutils/log.h>
21 #include <audio_utils/primitives.h>
22 #include <audio_utils/format.h>
23
24 void memcpy_by_audio_format(void *dst, audio_format_t dst_format,
25         const void *src, audio_format_t src_format, size_t count)
26 {
27     /* default cases for error falls through to fatal log below. */
28     if (dst_format == src_format) {
29         switch (dst_format) {
30         case AUDIO_FORMAT_PCM_16_BIT:
31         case AUDIO_FORMAT_PCM_FLOAT:
32         case AUDIO_FORMAT_PCM_8_BIT:
33         case AUDIO_FORMAT_PCM_24_BIT_PACKED:
34         case AUDIO_FORMAT_PCM_32_BIT:
35         case AUDIO_FORMAT_PCM_8_24_BIT:
36             memcpy(dst, src, count * audio_bytes_per_sample(dst_format));
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         default:
94             break;
95         }
96         break;
97     case AUDIO_FORMAT_PCM_24_BIT_PACKED:
98         switch (src_format) {
99         case AUDIO_FORMAT_PCM_16_BIT:
100             memcpy_to_p24_from_i16((uint8_t*)dst, (int16_t*)src, count);
101             return;
102         case AUDIO_FORMAT_PCM_FLOAT:
103             memcpy_to_p24_from_float((uint8_t*)dst, (float*)src, count);
104             return;
105         case AUDIO_FORMAT_PCM_32_BIT:
106             memcpy_to_p24_from_i32((uint8_t*)dst, (int32_t*)src, count);
107             return;
108         case AUDIO_FORMAT_PCM_8_24_BIT:
109             memcpy_to_p24_from_q8_23((uint8_t*)dst, (int32_t*)src, count);
110             return;
111         default:
112             break;
113         }
114         break;
115     case AUDIO_FORMAT_PCM_32_BIT:
116         switch (src_format) {
117         case AUDIO_FORMAT_PCM_16_BIT:
118             memcpy_to_i32_from_i16((int32_t*)dst, (int16_t*)src, count);
119             return;
120         case AUDIO_FORMAT_PCM_FLOAT:
121             memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count);
122             return;
123         case AUDIO_FORMAT_PCM_24_BIT_PACKED:
124             memcpy_to_i32_from_p24((int32_t*)dst, (uint8_t *)src, count);
125             return;
126         default:
127             break;
128         }
129         break;
130     case AUDIO_FORMAT_PCM_8_24_BIT:
131         switch (src_format) {
132         case AUDIO_FORMAT_PCM_16_BIT:
133             memcpy_to_q8_23_from_i16((int32_t*)dst, (int16_t*)src, count);
134             return;
135         case AUDIO_FORMAT_PCM_FLOAT:
136             memcpy_to_q8_23_from_float_with_clamp((int32_t*)dst, (float*)src, count);
137             return;
138         case AUDIO_FORMAT_PCM_24_BIT_PACKED: {
139             memcpy_to_q8_23_from_p24((int32_t *)dst, (uint8_t *)src, count);
140             return;
141         }
142         default:
143             break;
144         }
145         break;
146     default:
147         break;
148     }
149     LOG_ALWAYS_FATAL("invalid src format %#x for dst format %#x",
150             src_format, dst_format);
151 }
152
153 size_t memcpy_by_index_array_initialization_from_channel_mask(int8_t *idxary, size_t arysize,
154         audio_channel_mask_t dst_channel_mask, audio_channel_mask_t src_channel_mask)
155 {
156     const audio_channel_representation_t src_representation =
157             audio_channel_mask_get_representation(src_channel_mask);
158     const audio_channel_representation_t dst_representation =
159             audio_channel_mask_get_representation(dst_channel_mask);
160     const uint32_t src_bits = audio_channel_mask_get_bits(src_channel_mask);
161     const uint32_t dst_bits = audio_channel_mask_get_bits(dst_channel_mask);
162
163     switch (src_representation) {
164     case AUDIO_CHANNEL_REPRESENTATION_POSITION:
165         switch (dst_representation) {
166         case AUDIO_CHANNEL_REPRESENTATION_POSITION:
167             return memcpy_by_index_array_initialization(idxary, arysize,
168                     dst_bits, src_bits);
169         case AUDIO_CHANNEL_REPRESENTATION_INDEX:
170             return memcpy_by_index_array_initialization_dst_index(idxary, arysize,
171                     dst_bits, src_bits);
172         default:
173             return 0;
174         }
175         break;
176     case AUDIO_CHANNEL_REPRESENTATION_INDEX:
177         switch (dst_representation) {
178         case AUDIO_CHANNEL_REPRESENTATION_POSITION:
179             return memcpy_by_index_array_initialization_src_index(idxary, arysize,
180                     dst_bits, src_bits);
181         case AUDIO_CHANNEL_REPRESENTATION_INDEX:
182             return memcpy_by_index_array_initialization(idxary, arysize,
183                     dst_bits, src_bits);
184         default:
185             return 0;
186         }
187         break;
188     default:
189         return 0;
190     }
191 }