Home | History | Annotate | Download | only in av
      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 *******************************************************************************/
     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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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