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