• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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