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