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