1 /******************************************************************************
2  *
3  *  Copyright (C) 2004-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This module contains utility functions for dealing with SBC data frames
22  *  and codec capabilities.
23  *
24  ******************************************************************************/
25 
26 #include "common/bt_target.h"
27 #include "stack/a2d_api.h"
28 #include "stack/a2d_sbc.h"
29 #include "bta/bta_av_sbc.h"
30 #include "bta/utl.h"
31 #include "common/bt_defs.h"
32 
33 #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
34 #include "bta_av_int.h"
35 
36 #if BTA_DYNAMIC_MEMORY == FALSE
37 static tBTA_AV_SBC_UPS_CB bta_av_sbc_ups_cb;
38 #else
39 tBTA_AV_SBC_UPS_CB *bta_av_sbc_ups_cb_ptr;
40 #endif
41 
42 /*******************************************************************************
43 **
44 ** Function         bta_av_sbc_init_up_sample
45 **
46 ** Description      initialize the up sample
47 **
48 **                  src_sps: samples per second (source audio data)
49 **                  dst_sps: samples per second (converted audio data)
50 **                  bits: number of bits per pcm sample
51 **                  n_channels: number of channels (i.e. mono(1), stereo(2)...)
52 **
53 ** Returns          none
54 **
55 *******************************************************************************/
bta_av_sbc_init_up_sample(UINT32 src_sps,UINT32 dst_sps,UINT16 bits,UINT16 n_channels)56 void bta_av_sbc_init_up_sample (UINT32 src_sps, UINT32 dst_sps, UINT16 bits, UINT16 n_channels)
57 {
58     bta_av_sbc_ups_cb.cur_pos   = -1;
59     bta_av_sbc_ups_cb.src_sps   = src_sps;
60     bta_av_sbc_ups_cb.dst_sps   = dst_sps;
61     bta_av_sbc_ups_cb.bits      = bits;
62     bta_av_sbc_ups_cb.n_channels = n_channels;
63 
64     if (n_channels == 1) {
65         /* mono */
66         if (bits == 8) {
67             bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_8m;
68             bta_av_sbc_ups_cb.div   = 1;
69         } else {
70             bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_16m;
71             bta_av_sbc_ups_cb.div   = 2;
72         }
73     } else {
74         /* stereo */
75         if (bits == 8) {
76             bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_8s;
77             bta_av_sbc_ups_cb.div   = 2;
78         } else {
79             bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_16s;
80             bta_av_sbc_ups_cb.div   = 4;
81         }
82     }
83 }
84 
85 /*******************************************************************************
86 **
87 ** Function         bta_av_sbc_up_sample
88 **
89 ** Description      Given the source (p_src) audio data and
90 **                  source speed (src_sps, samples per second),
91 **                  This function converts it to audio data in the desired format
92 **
93 **                  p_src: the data buffer that holds the source audio data
94 **                  p_dst: the data buffer to hold the converted audio data
95 **                  src_samples: The number of source samples (number of bytes)
96 **                  dst_samples: The size of p_dst (number of bytes)
97 **
98 ** Note:            An AE reported an issue with this function.
99 **                  When called with bta_av_sbc_up_sample(src, uint8_array_dst..)
100 **                  the byte before uint8_array_dst may get overwritten.
101 **                  Using uint16_array_dst avoids the problem.
102 **                  This issue is related to endian-ness and is hard to resolve
103 **                  in a generic manner.
104 ** **************** Please use uint16 array as dst.
105 **
106 ** Returns          The number of bytes used in p_dst
107 **                  The number of bytes used in p_src (in *p_ret)
108 **
109 *******************************************************************************/
bta_av_sbc_up_sample(void * p_src,void * p_dst,UINT32 src_samples,UINT32 dst_samples,UINT32 * p_ret)110 int bta_av_sbc_up_sample (void *p_src, void *p_dst,
111                           UINT32 src_samples, UINT32 dst_samples,
112                           UINT32 *p_ret)
113 {
114     UINT32 src;
115     UINT32 dst;
116 
117     if (bta_av_sbc_ups_cb.p_act) {
118         src = src_samples / bta_av_sbc_ups_cb.div;
119         dst = dst_samples / bta_av_sbc_ups_cb.div;
120         return (*bta_av_sbc_ups_cb.p_act)(p_src, p_dst, src, dst, p_ret);
121     } else {
122         *p_ret = 0;
123         return 0;
124     }
125 }
126 
127 /*******************************************************************************
128 **
129 ** Function         bta_av_sbc_up_sample_16s (16bits-stereo)
130 **
131 ** Description      Given the source (p_src) audio data and
132 **                  source speed (src_sps, samples per second),
133 **                  This function converts it to audio data in the desired format
134 **
135 **                  p_src: the data buffer that holds the source audio data
136 **                  p_dst: the data buffer to hold the converted audio data
137 **                  src_samples: The number of source samples (in uint of 4 bytes)
138 **                  dst_samples: The size of p_dst (in uint of 4 bytes)
139 **
140 ** Returns          The number of bytes used in p_dst
141 **                  The number of bytes used in p_src (in *p_ret)
142 **
143 *******************************************************************************/
bta_av_sbc_up_sample_16s(void * p_src,void * p_dst,UINT32 src_samples,UINT32 dst_samples,UINT32 * p_ret)144 int bta_av_sbc_up_sample_16s (void *p_src, void *p_dst,
145                               UINT32 src_samples, UINT32 dst_samples,
146                               UINT32 *p_ret)
147 {
148     INT16   *p_src_tmp = (INT16 *)p_src;
149     INT16   *p_dst_tmp = (INT16 *)p_dst;
150     INT16   *p_worker1 = &bta_av_sbc_ups_cb.worker1;
151     INT16   *p_worker2 = &bta_av_sbc_ups_cb.worker2;
152     UINT32  src_sps = bta_av_sbc_ups_cb.src_sps;
153     UINT32  dst_sps = bta_av_sbc_ups_cb.dst_sps;
154 
155     while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
156         *p_dst_tmp++    = *p_worker1;
157         *p_dst_tmp++    = *p_worker2;
158 
159         bta_av_sbc_ups_cb.cur_pos -= src_sps;
160         dst_samples--;
161     }
162 
163     bta_av_sbc_ups_cb.cur_pos = dst_sps;
164 
165     while (src_samples-- && dst_samples) {
166         *p_worker1 = *p_src_tmp++;
167         *p_worker2 = *p_src_tmp++;
168 
169         do {
170             *p_dst_tmp++    = *p_worker1;
171             *p_dst_tmp++    = *p_worker2;
172 
173             bta_av_sbc_ups_cb.cur_pos -= src_sps;
174             dst_samples--;
175         } while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
176 
177         bta_av_sbc_ups_cb.cur_pos += dst_sps;
178     }
179 
180     if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
181         bta_av_sbc_ups_cb.cur_pos = 0;
182     }
183 
184     *p_ret = ((char *)p_src_tmp - (char *)p_src);
185     return ((char *)p_dst_tmp - (char *)p_dst);
186 }
187 
188 /*******************************************************************************
189 **
190 ** Function         bta_av_sbc_up_sample_16m (16bits-mono)
191 **
192 ** Description      Given the source (p_src) audio data and
193 **                  source speed (src_sps, samples per second),
194 **                  This function converts it to audio data in the desired format
195 **
196 **                  p_src: the data buffer that holds the source audio data
197 **                  p_dst: the data buffer to hold the converted audio data
198 **                  src_samples: The number of source samples (in uint of 2 bytes)
199 **                  dst_samples: The size of p_dst (in uint of 2 bytes)
200 **
201 ** Returns          The number of bytes used in p_dst
202 **                  The number of bytes used in p_src (in *p_ret)
203 **
204 *******************************************************************************/
bta_av_sbc_up_sample_16m(void * p_src,void * p_dst,UINT32 src_samples,UINT32 dst_samples,UINT32 * p_ret)205 int bta_av_sbc_up_sample_16m (void *p_src, void *p_dst,
206                               UINT32 src_samples, UINT32 dst_samples,
207                               UINT32 *p_ret)
208 {
209     INT16   *p_src_tmp = (INT16 *)p_src;
210     INT16   *p_dst_tmp = (INT16 *)p_dst;
211     INT16   *p_worker = &bta_av_sbc_ups_cb.worker1;
212     UINT32  src_sps = bta_av_sbc_ups_cb.src_sps;
213     UINT32  dst_sps = bta_av_sbc_ups_cb.dst_sps;
214 
215     while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
216         *p_dst_tmp++ = *p_worker;
217         *p_dst_tmp++ = *p_worker;
218 
219         bta_av_sbc_ups_cb.cur_pos -= src_sps;
220         dst_samples--;
221         dst_samples--;
222     }
223 
224 
225     bta_av_sbc_ups_cb.cur_pos = dst_sps;
226 
227     while (src_samples-- && dst_samples) {
228         *p_worker = *p_src_tmp++;
229 
230         do {
231             *p_dst_tmp++ = *p_worker;
232             *p_dst_tmp++ = *p_worker;
233 
234             bta_av_sbc_ups_cb.cur_pos -= src_sps;
235             dst_samples--;
236             dst_samples--;
237 
238         } while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
239 
240         bta_av_sbc_ups_cb.cur_pos += dst_sps;
241     }
242 
243     if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
244         bta_av_sbc_ups_cb.cur_pos = 0;
245     }
246 
247     *p_ret = ((char *)p_src_tmp - (char *)p_src);
248     return ((char *)p_dst_tmp - (char *)p_dst);
249 }
250 
251 /*******************************************************************************
252 **
253 ** Function         bta_av_sbc_up_sample_8s (8bits-stereo)
254 **
255 ** Description      Given the source (p_src) audio data and
256 **                  source speed (src_sps, samples per second),
257 **                  This function converts it to audio data in the desired format
258 **
259 **                  p_src: the data buffer that holds the source audio data
260 **                  p_dst: the data buffer to hold the converted audio data
261 **                  src_samples: The number of source samples (in uint of 2 bytes)
262 **                  dst_samples: The size of p_dst (in uint of 2 bytes)
263 **
264 ** Returns          The number of bytes used in p_dst
265 **                  The number of bytes used in p_src (in *p_ret)
266 **
267 *******************************************************************************/
bta_av_sbc_up_sample_8s(void * p_src,void * p_dst,UINT32 src_samples,UINT32 dst_samples,UINT32 * p_ret)268 int bta_av_sbc_up_sample_8s (void *p_src, void *p_dst,
269                              UINT32 src_samples, UINT32 dst_samples,
270                              UINT32 *p_ret)
271 {
272     UINT8   *p_src_tmp = (UINT8 *)p_src;
273     INT16   *p_dst_tmp = (INT16 *)p_dst;
274     INT16   *p_worker1 = &bta_av_sbc_ups_cb.worker1;
275     INT16   *p_worker2 = &bta_av_sbc_ups_cb.worker2;
276     UINT32  src_sps = bta_av_sbc_ups_cb.src_sps;
277     UINT32  dst_sps = bta_av_sbc_ups_cb.dst_sps;
278 
279     while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
280         *p_dst_tmp++    = *p_worker1;
281         *p_dst_tmp++    = *p_worker2;
282 
283         bta_av_sbc_ups_cb.cur_pos -= src_sps;
284         dst_samples--;
285         dst_samples--;
286     }
287 
288     bta_av_sbc_ups_cb.cur_pos = dst_sps;
289 
290     while (src_samples -- && dst_samples) {
291         *p_worker1 = *(UINT8 *)p_src_tmp++;
292         *p_worker1 -= 0x80;
293         *p_worker1 <<= 8;
294         *p_worker2 = *(UINT8 *)p_src_tmp++;
295         *p_worker2 -= 0x80;
296         *p_worker2 <<= 8;
297 
298         do {
299             *p_dst_tmp++    = *p_worker1;
300             *p_dst_tmp++    = *p_worker2;
301 
302             bta_av_sbc_ups_cb.cur_pos -= src_sps;
303             dst_samples--;
304             dst_samples--;
305         } while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
306 
307         bta_av_sbc_ups_cb.cur_pos += dst_sps;
308     }
309 
310     if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
311         bta_av_sbc_ups_cb.cur_pos = 0;
312     }
313 
314     *p_ret = ((char *)p_src_tmp - (char *)p_src);
315     return ((char *)p_dst_tmp - (char *)p_dst);
316 }
317 
318 /*******************************************************************************
319 **
320 ** Function         bta_av_sbc_up_sample_8m (8bits-mono)
321 **
322 ** Description      Given the source (p_src) audio data and
323 **                  source speed (src_sps, samples per second),
324 **                  This function converts it to audio data in the desired format
325 **
326 **                  p_src: the data buffer that holds the source audio data
327 **                  p_dst: the data buffer to hold the converted audio data
328 **                  src_samples: The number of source samples (number of bytes)
329 **                  dst_samples: The size of p_dst (number of bytes)
330 **
331 ** Returns          The number of bytes used in p_dst
332 **                  The number of bytes used in p_src (in *p_ret)
333 **
334 *******************************************************************************/
bta_av_sbc_up_sample_8m(void * p_src,void * p_dst,UINT32 src_samples,UINT32 dst_samples,UINT32 * p_ret)335 int bta_av_sbc_up_sample_8m (void *p_src, void *p_dst,
336                              UINT32 src_samples, UINT32 dst_samples,
337                              UINT32 *p_ret)
338 {
339     UINT8   *p_src_tmp = (UINT8 *)p_src;
340     INT16   *p_dst_tmp = (INT16 *)p_dst;
341     INT16   *p_worker = &bta_av_sbc_ups_cb.worker1;
342     UINT32  src_sps = bta_av_sbc_ups_cb.src_sps;
343     UINT32  dst_sps = bta_av_sbc_ups_cb.dst_sps;
344 
345     while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
346         *p_dst_tmp++ = *p_worker;
347         *p_dst_tmp++ = *p_worker;
348 
349         bta_av_sbc_ups_cb.cur_pos -= src_sps;
350         dst_samples -= 4;
351     }
352 
353 
354     bta_av_sbc_ups_cb.cur_pos = dst_sps;
355 
356     while (src_samples-- && dst_samples) {
357         *p_worker = *(UINT8 *)p_src_tmp++;
358         *p_worker -= 0x80;
359         *p_worker <<= 8;
360 
361         do {
362             *p_dst_tmp++ = *p_worker;
363             *p_dst_tmp++ = *p_worker;
364 
365             bta_av_sbc_ups_cb.cur_pos -= src_sps;
366             dst_samples -= 4;
367 
368         } while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
369 
370         bta_av_sbc_ups_cb.cur_pos += dst_sps;
371     }
372 
373     if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
374         bta_av_sbc_ups_cb.cur_pos = 0;
375     }
376 
377     *p_ret = ((char *)p_src_tmp - (char *)p_src);
378     return ((char *)p_dst_tmp - (char *)p_dst);
379 }
380 
381 /*******************************************************************************
382 **
383 ** Function         bta_av_sbc_cfg_for_cap
384 **
385 ** Description      Determine the preferred SBC codec configuration for the
386 **                  given codec capabilities.  The function is passed the
387 **                  preferred codec configuration and the peer codec
388 **                  capabilities for the stream.  The function attempts to
389 **                  match the preferred capabilities with the configuration
390 **                  as best it can.  The resulting codec configuration is
391 **                  returned in the same memory used for the capabilities.
392 **
393 ** Returns          0 if ok, nonzero if error.
394 **                  Codec configuration in p_cap.
395 **
396 *******************************************************************************/
bta_av_sbc_cfg_for_cap(UINT8 * p_peer,tA2D_SBC_CIE * p_cap,tA2D_SBC_CIE * p_pref)397 UINT8 bta_av_sbc_cfg_for_cap(UINT8 *p_peer, tA2D_SBC_CIE *p_cap, tA2D_SBC_CIE *p_pref)
398 {
399     UINT8           status = A2D_SUCCESS;
400     tA2D_SBC_CIE    peer_cie;
401     UNUSED(p_cap);
402 
403     /* parse peer capabilities */
404     if ((status = A2D_ParsSbcInfo(&peer_cie, p_peer, TRUE)) != 0) {
405         return status;
406     }
407 
408     /* Check if the peer supports our channel mode */
409     if (peer_cie.ch_mode & p_pref->ch_mode) {
410         peer_cie.ch_mode = p_pref->ch_mode;
411     } else {
412         APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: ch_mode(0x%02X) not supported", p_pref->ch_mode);
413         return A2D_FAIL;
414     }
415 
416     /* Check if the peer supports our sampling freq */
417     if (peer_cie.samp_freq & p_pref->samp_freq) {
418         peer_cie.samp_freq = p_pref->samp_freq;
419     } else {
420         APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: samp_freq(0x%02X) not supported", p_pref->samp_freq);
421         return A2D_FAIL;
422     }
423 
424     /* Check if the peer supports our block len */
425     if (peer_cie.block_len & p_pref->block_len) {
426         peer_cie.block_len = p_pref->block_len;
427     } else {
428         APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: block_len(0x%02X) not supported", p_pref->block_len);
429         return A2D_FAIL;
430     }
431 
432     /* Check if the peer supports our num subbands */
433     if (peer_cie.num_subbands & p_pref->num_subbands) {
434         peer_cie.num_subbands = p_pref->num_subbands;
435     } else {
436         APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: num_subbands(0x%02X) not supported", p_pref->num_subbands);
437         return A2D_FAIL;
438     }
439 
440     /* Check if the peer supports our alloc method */
441     if (peer_cie.alloc_mthd & p_pref->alloc_mthd) {
442         peer_cie.alloc_mthd = p_pref->alloc_mthd;
443     } else {
444         APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: alloc_mthd(0x%02X) not supported", p_pref->alloc_mthd);
445         return A2D_FAIL;
446     }
447 
448     /* max bitpool */
449     if (p_pref->max_bitpool != 0 && p_pref->max_bitpool < peer_cie.max_bitpool) {
450         peer_cie.max_bitpool = p_pref->max_bitpool;
451     }
452 
453     /* min bitpool */
454     if (p_pref->min_bitpool != 0 && p_pref->min_bitpool > peer_cie.min_bitpool) {
455         peer_cie.min_bitpool = p_pref->min_bitpool;
456     }
457 
458     if (status == A2D_SUCCESS) {
459         /* build configuration */
460         A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, &peer_cie, p_peer);
461     }
462     return status;
463 }
464 
465 /*******************************************************************************
466 **
467 ** Function         bta_av_sbc_cfg_matches_cap
468 **
469 ** Description      This function checks whether an SBC codec configuration
470 **                  matched with capabilities. Here we check subset.
471 **
472 ** Returns          0 if ok, nonzero if error.
473 **
474 *******************************************************************************/
bta_av_sbc_cfg_matches_cap(UINT8 * p_cfg,tA2D_SBC_CIE * p_cap)475 UINT8 bta_av_sbc_cfg_matches_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
476 {
477     UINT8           status = 0;
478     tA2D_SBC_CIE    cfg_cie;
479 
480     /* parse configuration */
481     if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, TRUE)) != 0) {
482         APPL_TRACE_ERROR(" bta_av_sbc_cfg_matches_cap Parsing Failed %d", status);
483         return status;
484     }
485 
486     /* verify that each parameter is in range */
487 
488     APPL_TRACE_DEBUG(" FREQ peer: 0%x, capability  0%x", cfg_cie.samp_freq, p_cap->samp_freq);
489     APPL_TRACE_DEBUG(" CH_MODE peer: 0%x, capability  0%x", cfg_cie.ch_mode, p_cap->ch_mode);
490     APPL_TRACE_DEBUG(" BLOCK_LEN peer: 0%x, capability  0%x", cfg_cie.block_len, p_cap->block_len);
491     APPL_TRACE_DEBUG(" SUB_BAND peer: 0%x, capability  0%x", cfg_cie.num_subbands, p_cap->num_subbands);
492     APPL_TRACE_DEBUG(" ALLOC_MTHD peer: 0%x, capability  0%x", cfg_cie.alloc_mthd, p_cap->alloc_mthd);
493     APPL_TRACE_DEBUG(" MAX_BitPool peer: 0%x, capability  0%x", cfg_cie.max_bitpool, p_cap->max_bitpool);
494     APPL_TRACE_DEBUG(" Min_bitpool peer: 0%x, capability  0%x", cfg_cie.min_bitpool, p_cap->min_bitpool);
495 
496     /* sampling frequency */
497     if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) {
498         status = A2D_NS_SAMP_FREQ;
499     }
500     /* channel mode */
501     else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) {
502         status = A2D_NS_CH_MODE;
503     }
504     /* block length */
505     else if ((cfg_cie.block_len & p_cap->block_len) == 0) {
506         status = A2D_BAD_BLOCK_LEN;
507     }
508     /* subbands */
509     else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) {
510         status = A2D_NS_SUBBANDS;
511     }
512     /* allocation method */
513     else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0) {
514         status = A2D_NS_ALLOC_MTHD;
515     }
516     /* max bitpool */
517     else if (cfg_cie.max_bitpool > p_cap->max_bitpool) {
518         status = A2D_NS_MAX_BITPOOL;
519     }
520     /* min bitpool */
521     else if (cfg_cie.min_bitpool < p_cap->min_bitpool) {
522         status = A2D_NS_MIN_BITPOOL;
523     }
524 
525     return status;
526 }
527 
528 
529 /*******************************************************************************
530 **
531 ** Function         bta_av_sbc_cfg_in_cap
532 **
533 ** Description      This function checks whether an SBC codec configuration
534 **                  is allowable for the given codec capabilities.
535 **
536 ** Returns          0 if ok, nonzero if error.
537 **
538 *******************************************************************************/
bta_av_sbc_cfg_in_cap(UINT8 * p_cfg,tA2D_SBC_CIE * p_cap)539 UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
540 {
541     UINT8           status = 0;
542     tA2D_SBC_CIE    cfg_cie;
543 
544     /* parse configuration */
545     if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, FALSE)) != 0) {
546         return status;
547     }
548 
549     /* verify that each parameter is in range */
550 
551 
552     /* sampling frequency */
553     if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) {
554         status = A2D_NS_SAMP_FREQ;
555     }
556     /* channel mode */
557     else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) {
558         status = A2D_NS_CH_MODE;
559     }
560     /* block length */
561     else if ((cfg_cie.block_len & p_cap->block_len) == 0) {
562         status = A2D_BAD_BLOCK_LEN;
563     }
564     /* subbands */
565     else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) {
566         status = A2D_NS_SUBBANDS;
567     }
568     /* allocation method */
569     else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0) {
570         status = A2D_NS_ALLOC_MTHD;
571     }
572     /* max bitpool */
573     else if (cfg_cie.max_bitpool > p_cap->max_bitpool) {
574         status = A2D_NS_MAX_BITPOOL;
575     }
576     /* min bitpool */
577     else if (cfg_cie.min_bitpool < p_cap->min_bitpool) {
578         status = A2D_NS_MIN_BITPOOL;
579     }
580 
581     return status;
582 }
583 
584 /*******************************************************************************
585 **
586 ** Function         bta_av_sbc_bld_hdr
587 **
588 ** Description      This function builds the packet header for MPF1.
589 **
590 ** Returns          void
591 **
592 *******************************************************************************/
bta_av_sbc_bld_hdr(BT_HDR * p_buf,UINT16 fr_per_pkt)593 void bta_av_sbc_bld_hdr(BT_HDR *p_buf, UINT16 fr_per_pkt)
594 {
595     UINT8   *p;
596 
597     p_buf->offset -= BTA_AV_SBC_HDR_SIZE;
598     p = (UINT8 *) (p_buf + 1) + p_buf->offset;
599     p_buf->len += BTA_AV_SBC_HDR_SIZE;
600     A2D_BldSbcMplHdr(p, FALSE, FALSE, FALSE, (UINT8) fr_per_pkt);
601 }
602 
603 #endif /* #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */
604