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 #ifndef ANDROID_AUDIO_CHANNELS_H
18 #define ANDROID_AUDIO_CHANNELS_H
19
20 #include <system/audio.h>
21
22 #ifdef __cplusplus
23
24 // New development in channels namespace.
25 namespace android::audio_utils::channels {
26
27 /**
28 * Returns a particular side (left, right, center) associated
29 * with a channel position mask bit index.
30 * This is a fixed geometrical constant for a given channel mask.
31 *
32 * For the channel mask spec, see system/media/audio/include/system/audio*.h.
33 *
34 * Special Note: if there are two LFE speakers and bass management is used,
35 * then AUDIO_CHANNEL_OUT_LOW_FREQUENCY speaker is on the left side and receives
36 * all bass from left side speakers that they cannot reproduce,
37 * likewise AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2 is used for the right side
38 * (https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BS.2159-4-2012-PDF-E.pdf#page=15).
39 *
40 * For simplicity, both AUDIO_CHANNEL_OUT_LOW_FREQUENCY and
41 * AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2 are assigned to the center channel,
42 * which is a safe approximation given the lack of directionality of LFE.
43 * Specific handling for the presence of two LFE speakers must be handled
44 * elsewhere.
45 *
46 * \param idx index of bit in the channel position mask.
47 * \return side constant.
48 */
49 enum AUDIO_GEOMETRY_SIDE {
50 AUDIO_GEOMETRY_SIDE_LEFT,
51 AUDIO_GEOMETRY_SIDE_CENTER,
52 AUDIO_GEOMETRY_SIDE_RIGHT,
53 };
54 // static constexpr arrays cannot be declared in block scope.
55 // inline allows multiple definition, single object address.
56 constexpr inline AUDIO_GEOMETRY_SIDE kSideFromChannelIdx[] = {
57 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_FRONT_LEFT = 0x1u,
58 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_FRONT_RIGHT = 0x2u,
59 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4u,
60 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8u,
61 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_BACK_LEFT = 0x10u,
62 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_BACK_RIGHT = 0x20u,
63 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40u,
64 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80u,
65 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100u,
66 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_SIDE_LEFT = 0x200u,
67 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_SIDE_RIGHT = 0x400u,
68 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800u,
69 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000u,
70 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000u,
71 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000u,
72 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 0x8000u,
73 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000u,
74 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000u,
75 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT = 0x40000u,
76 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT = 0x80000u,
77 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_LEFT = 0x100000u,
78 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_CENTER = 0x200000u,
79 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_RIGHT = 0x400000u,
80 AUDIO_GEOMETRY_SIDE_CENTER, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2 = 0x800000u,
81 AUDIO_GEOMETRY_SIDE_LEFT, // AUDIO_CHANNEL_OUT_FRONT_WIDE_LEFT = 0x1000000u
82 AUDIO_GEOMETRY_SIDE_RIGHT, // AUDIO_CHANNEL_OUT_FRONT_WIDE_RIGHT = 0x2000000u
83 };
sideFromChannelIdx(size_t idx)84 constexpr inline AUDIO_GEOMETRY_SIDE sideFromChannelIdx(size_t idx) {
85 static_assert(std::size(kSideFromChannelIdx) == FCC_26);
86 if (idx < std::size(kSideFromChannelIdx)) return kSideFromChannelIdx[idx];
87 return AUDIO_GEOMETRY_SIDE_CENTER;
88 }
89
90 /**
91 * Returns a particular height (bottom, middle, top) associated
92 * with a channel position mask bit index.
93 * This is a fixed geometrical constant for a given channel mask.
94 *
95 * For the channel mask spec, see system/media/audio/include/system/audio*.h.
96 *
97 * \param idx index of bit in the channel position mask.
98 * \return height constant.
99 */
100 enum AUDIO_GEOMETRY_HEIGHT {
101 AUDIO_GEOMETRY_HEIGHT_BOTTOM,
102 AUDIO_GEOMETRY_HEIGHT_MIDDLE,
103 AUDIO_GEOMETRY_HEIGHT_TOP,
104 };
105 // static constexpr arrays cannot be declared in block scope.
106 // inline allows multiple definition, single object address.
107 constexpr inline AUDIO_GEOMETRY_HEIGHT kHeightFromChannelIdx [] = {
108 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_LEFT = 0x1u,
109 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_RIGHT = 0x2u,
110 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4u,
111 AUDIO_GEOMETRY_HEIGHT_BOTTOM, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8u,
112 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_BACK_LEFT = 0x10u,
113 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_BACK_RIGHT = 0x20u,
114 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40u,
115 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80u,
116 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100u,
117 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_SIDE_LEFT = 0x200u,
118 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_SIDE_RIGHT = 0x400u,
119 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800u,
120 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000u,
121 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000u,
122 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000u,
123 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 0x8000u,
124 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000u,
125 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000u,
126 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT = 0x40000u,
127 AUDIO_GEOMETRY_HEIGHT_TOP, // AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT = 0x80000u,
128 AUDIO_GEOMETRY_HEIGHT_BOTTOM, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_LEFT = 0x100000u,
129 AUDIO_GEOMETRY_HEIGHT_BOTTOM, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_CENTER = 0x200000u,
130 AUDIO_GEOMETRY_HEIGHT_BOTTOM, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_RIGHT = 0x400000u,
131 AUDIO_GEOMETRY_HEIGHT_BOTTOM, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2 = 0x800000u,
132 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_WIDE_LEFT = 0x1000000u
133 AUDIO_GEOMETRY_HEIGHT_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_WIDE_RIGHT = 0x2000000u
134 };
heightFromChannelIdx(size_t idx)135 constexpr inline AUDIO_GEOMETRY_HEIGHT heightFromChannelIdx(size_t idx) {
136 static_assert(std::size(kHeightFromChannelIdx) == FCC_26);
137 if (idx < std::size(kHeightFromChannelIdx)) return kHeightFromChannelIdx[idx];
138 return AUDIO_GEOMETRY_HEIGHT_MIDDLE;
139 }
140
141 /**
142 * Returns a particular depth (front, middle (aka side), back) associated
143 * with a channel position mask bit index.
144 * This is a fixed geometrical constant for a given channel mask.
145 *
146 * For the channel mask spec, see system/media/audio/include/system/audio*.h.
147 *
148 * \param idx index of bit in the channel position mask.
149 * \return depth constant.
150 */
151 enum AUDIO_GEOMETRY_DEPTH {
152 AUDIO_GEOMETRY_DEPTH_FRONT,
153 AUDIO_GEOMETRY_DEPTH_MIDDLE,
154 AUDIO_GEOMETRY_DEPTH_BACK,
155 };
156 // static constexpr arrays cannot be declared in block scope.
157 // inline allows multiple definition, single object address.
158 constexpr inline AUDIO_GEOMETRY_DEPTH kDepthFromChannelIdx[] = {
159 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_FRONT_LEFT = 0x1u,
160 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_FRONT_RIGHT = 0x2u,
161 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4u,
162 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8u,
163 AUDIO_GEOMETRY_DEPTH_BACK, // AUDIO_CHANNEL_OUT_BACK_LEFT = 0x10u,
164 AUDIO_GEOMETRY_DEPTH_BACK, // AUDIO_CHANNEL_OUT_BACK_RIGHT = 0x20u,
165 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40u,
166 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80u,
167 AUDIO_GEOMETRY_DEPTH_BACK, // AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100u,
168 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_SIDE_LEFT = 0x200u,
169 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_SIDE_RIGHT = 0x400u,
170 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800u,
171 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000u,
172 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000u,
173 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000u,
174 AUDIO_GEOMETRY_DEPTH_BACK, // AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 0x8000u,
175 AUDIO_GEOMETRY_DEPTH_BACK, // AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000u,
176 AUDIO_GEOMETRY_DEPTH_BACK, // AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000u,
177 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT = 0x40000u,
178 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT = 0x80000u,
179 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_LEFT = 0x100000u,
180 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_CENTER = 0x200000u,
181 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_RIGHT = 0x400000u,
182 AUDIO_GEOMETRY_DEPTH_FRONT, // AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2 = 0x800000u,
183 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_WIDE_LEFT = 0x1000000u
184 AUDIO_GEOMETRY_DEPTH_MIDDLE, // AUDIO_CHANNEL_OUT_FRONT_WIDE_RIGHT = 0x2000000u
185 };
depthFromChannelIdx(size_t idx)186 constexpr inline AUDIO_GEOMETRY_DEPTH depthFromChannelIdx(size_t idx) {
187 static_assert(std::size(kDepthFromChannelIdx) == FCC_26);
188 if (idx < std::size(kDepthFromChannelIdx)) return kDepthFromChannelIdx[idx];
189 return AUDIO_GEOMETRY_DEPTH_FRONT;
190 }
191
192 /**
193 * Returns the pair channel position mask bit index as determined by
194 * AUDIO_GEOMETRY_SIDE_LEFT and AUDIO_GEOMETRY_SIDE_RIGHT characteristics.
195 *
196 * For example a bit index of 0 (AUDIO_CHANNEL_OUT_FRONT_LEFT) returns
197 * a pair bit index of 1 (AUDIO_CHANNEL_OUT_FRONT_RIGHT).
198 *
199 * If there is no left/right characteristic, then -1 is returned.
200 * For example, a bit index of 2 (AUDIO_CHANNEL_OUT_FRONT_CENTER) returns
201 * a pair bit index of -1 (doesn't exist).
202 *
203 * For the channel mask spec, see system/media/audio/include/system/audio*.h.
204 *
205 * \param idx index of bit in the channel position mask.
206 * \return index of bit of the pair if non-negative, or -1 if it doesn't exist.
207 */
208
209 #pragma push_macro("CHANNEL_ASSOCIATE")
210 #undef CHANNEL_ASSOCIATE
211 #define CHANNEL_ASSOCIATE(x, y) \
212 [__builtin_ctz(x)] = __builtin_ctz(y), [__builtin_ctz(y)] = __builtin_ctz(x),
213
214 #pragma GCC diagnostic push
215 #pragma GCC diagnostic ignored "-Winitializer-overrides" // we use override array assignment
216
217 constexpr inline int kPairIdxFromChannelIdx[FCC_26] = {
218 [ 0 ... 25 ] = -1, // everything defaults to -1 unless overridden below.
219 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_FRONT_LEFT, AUDIO_CHANNEL_OUT_FRONT_RIGHT)
220 // AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4u,
221 // AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8u,
222 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_BACK_LEFT, AUDIO_CHANNEL_OUT_BACK_RIGHT)
223 CHANNEL_ASSOCIATE(
224 AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER)
225 // AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100u,
226 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_SIDE_LEFT, AUDIO_CHANNEL_OUT_SIDE_RIGHT)
227 // AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800u,
228 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT, AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT)
229 // AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000u,
230 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT, AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT)
231 // AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000u,
232 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT, AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT)
233 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_BOTTOM_FRONT_LEFT, AUDIO_CHANNEL_OUT_BOTTOM_FRONT_RIGHT)
234 // AUDIO_CHANNEL_OUT_BOTTOM_FRONT_CENTER = 0x200000u,
235 // AUDIO_CHANNEL_OUT_LOW_FREQUENCY_2 = 0x800000u,
236 CHANNEL_ASSOCIATE(AUDIO_CHANNEL_OUT_FRONT_WIDE_LEFT, AUDIO_CHANNEL_OUT_FRONT_WIDE_RIGHT)
237 };
238 #pragma GCC diagnostic pop
239 #pragma pop_macro("CHANNEL_ASSOCIATE")
240
pairIdxFromChannelIdx(size_t idx)241 constexpr inline ssize_t pairIdxFromChannelIdx(size_t idx) {
242 static_assert(std::size(kPairIdxFromChannelIdx) == FCC_26);
243 if (idx < std::size(kPairIdxFromChannelIdx)) return kPairIdxFromChannelIdx[idx];
244 return -1;
245 }
246
247 } // android::audio_utils::channels
248
249 #endif // __cplusplus
250
251 /** \cond */
252 __BEGIN_DECLS
253 /** \endcond */
254
255 /**
256 * Expands or contracts sample data from one interleaved channel format to another.
257 * Expanded channels are filled with zeros and put at the end of each audio frame.
258 * Contracted channels are omitted from the end of each audio frame.
259 *
260 * \param in_buff points to the buffer of samples
261 * \param in_buff_chans Specifies the number of channels in the input buffer.
262 * \param out_buff points to the buffer to receive converted samples.
263 * \param out_buff_chans Specifies the number of channels in the output buffer.
264 * \param sample_size_in_bytes Specifies the number of bytes per sample. 1, 2, 3, 4 are
265 * currently valid.
266 * \param num_in_bytes size of input buffer in bytes
267 *
268 * \return
269 * the number of bytes of output data or 0 if an error occurs.
270 *
271 * \note
272 * The out and sums buffers must either be completely separate (non-overlapping), or
273 * they must both start at the same address. Partially overlapping buffers are not supported.
274 */
275 size_t adjust_channels(const void* in_buff, size_t in_buff_chans,
276 void* out_buff, size_t out_buff_chans,
277 unsigned sample_size_in_bytes, size_t num_in_bytes);
278
279 /**
280 * Expands or contracts sample data from one interleaved channel format to another.
281 * Extra expanded channels are left alone in the output buffer.
282 * Contracted channels are omitted from the end of each audio frame.
283 *
284 * \param in_buff points to the buffer of samples
285 * \param in_buff_chans Specifies the number of channels in the input buffer.
286 * \param out_buff points to the buffer to receive converted samples.
287 * \param out_buff_chans Specifies the number of channels in the output buffer.
288 * \param sample_size_in_bytes Specifies the number of bytes per sample. 1, 2, 3, 4 are
289 * currently valid.
290 * \param num_in_bytes size of input buffer in bytes
291 *
292 * \return
293 * the number of bytes of output data or 0 if an error occurs.
294 *
295 * \note
296 * The out and in buffers must either be completely separate (non-overlapping), or
297 * they must both start at the same address. Partially overlapping buffers are not supported.
298 */
299 size_t adjust_selected_channels(const void* in_buff, size_t in_buff_chans,
300 void* out_buff, size_t out_buff_chans,
301 unsigned sample_size_in_bytes, size_t num_in_bytes);
302
303 /**
304 * Expands or contracts sample data from one interleaved channel format to another.
305 * Extra expanded channels are interleaved in from the end of the input buffer.
306 * Contracted channels are copied to the end of the output buffer.
307 *
308 * \param in_buff points to the buffer of samples.
309 * \param in_buff_chans Specifies the number of channels in the input buffer.
310 * \param out_buff points to the buffer to receive converted samples.
311 * \param out_buff_chans Specifies the number of channels in the output buffer.
312 * \param sample_size_in_bytes Specifies the number of bytes per sample. 1, 2, 3, 4 are
313 * currently valid.
314 * \param num_in_bytes size of input buffer in bytes.
315 *
316 * \return
317 * the number of bytes of output data or 0 if an error occurs.
318 *
319 * \note
320 * The out and in buffers must be the same length.
321 * The out and in buffers must either be completely separate (non-overlapping), or
322 * they must both start at the same address. Partially overlapping buffers are not supported.
323 */
324 size_t adjust_channels_non_destructive(const void* in_buff, size_t in_buff_chans,
325 void* out_buff, size_t out_buff_chans,
326 unsigned sample_size_in_bytes, size_t num_in_bytes);
327
328 /** \cond */
329 __END_DECLS
330 /** \endcond */
331
332 #endif // !ANDROID_AUDIO_CHANNELS_H
333