Home | History | Annotate | Download | only in dm
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-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 file contains the down sampling utility to convert PCM samples in
     22  *  16k/32k/48k/44.1k/22050/11025 sampling rate into 8K/16bits samples
     23  *  required for SCO channel format. One API function isprovided and only
     24  *  possible to be used when transmitting SCO data is sent via HCI
     25  *  interface.
     26  *
     27  ******************************************************************************/
     28 #include <string.h>
     29 #include "bta_api.h"
     30 #include "bta_sys.h"
     31 
     32 #if (BTM_SCO_HCI_INCLUDED == TRUE)
     33 
     34 #ifndef BTA_DM_SCO_DEBUG
     35 #define BTA_DM_SCO_DEBUG    FALSE
     36 #endif
     37 /*****************************************************************************
     38 **  Constants
     39 *****************************************************************************/
     40 
     41 #define BTA_DM_PCM_OVERLAP_SIZE			     48
     42 
     43 #define BTA_DM_PCM_SMPL_RATE_44100     44100
     44 #define BTA_DM_PCM_SMPL_RATE_22050     22050
     45 #define BTA_DM_PCM_SMPL_RATE_11025     11025
     46 
     47 /*****************************************************************************
     48 **  Data types for PCM Resampling utility
     49 *****************************************************************************/
     50 
     51 typedef INT32   (*PCONVERT_TO_BT_FILTERED)  (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
     52                              UINT32 dwSrcSps,INT32 *pLastCurPos, UINT8 *pOverlapArea);
     53 typedef INT32   (*PCONVERT_TO_BT_NOFILTER)  (void *pSrc, void *pDst, UINT32 dwSrcSamples,
     54                                              UINT32 dwSrcSps);
     55 typedef struct
     56 {
     57     UINT8               overlap_area[BTA_DM_PCM_OVERLAP_SIZE * 4];
     58     UINT32              cur_pos;    /* current position */
     59     UINT32              src_sps;    /* samples per second (source audio data) */
     60     PCONVERT_TO_BT_FILTERED     filter;    /* the action function to do the
     61                                     conversion 44100, 22050, 11025*/
     62     PCONVERT_TO_BT_NOFILTER     nofilter;    /* the action function to do
     63                                         the conversion 48000, 32000, 16000*/
     64     UINT32              bits;       /* number of bits per pcm sample */
     65     UINT32              n_channels; /* number of channels (i.e. mono(1), stereo(2)...) */
     66     UINT32              sample_size;
     67     UINT32              can_be_filtered;
     68     UINT32	            divisor;
     69 } tBTA_DM_PCM_RESAMPLE_CB;
     70 
     71 tBTA_DM_PCM_RESAMPLE_CB bta_dm_pcm_cb;
     72 
     73 /*****************************************************************************
     74 **  Macro Definition
     75 *****************************************************************************/
     76 
     77 
     78 #define CHECK_SATURATION16(x)                                           \
     79             if (x > 32767)                                              \
     80                 x = 32767;                                              \
     81             else if (x < -32768)                                        \
     82                 x = -32768;
     83 
     84 ////////////////////////////////////////////////////////////////////////////////////////////////////
     85 //
     86 #define CONVERT_44100_TO_BLUETOOTH(pStart, pEnd)                            \
     87     {                                                                       \
     88         INT32         out1, out2, out3, out4, out5;                         \
     89         SRC_TYPE    *pS = (SRC_TYPE *)pStart;                               \
     90         SRC_TYPE    *pSEnd = (SRC_TYPE *)pEnd;                              \
     91                                                                             \
     92         while (pS < pSEnd)                                                  \
     93         {                                                                   \
     94             CurrentPos -= 8000;                                             \
     95                                                                             \
     96             if (CurrentPos >= 0)                                            \
     97             {                                                               \
     98                 pS += SRC_CHANNELS;                                         \
     99                 continue;                                                   \
    100             }                                                               \
    101             CurrentPos += dwSrcSps;                                         \
    102                                                                             \
    103             out1 = (SRC_SAMPLE(0) * 1587)                                   \
    104                  + ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 1522)                \
    105                  + ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1337)                \
    106                  + ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 1058);               \
    107                                                                             \
    108             out1 = out1 / 30000;                                            \
    109                                                                             \
    110             out2 = ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 725)                 \
    111                  + ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 384)                 \
    112                  + ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 79);                 \
    113                                                                             \
    114             out2 = out2 / 30000;                                            \
    115                                                                             \
    116             out3 = ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 156)                 \
    117                  + ((SRC_SAMPLE(8) + SRC_SAMPLE(-8)) * 298)                 \
    118                  + ((SRC_SAMPLE(9) + SRC_SAMPLE(-9)) * 345);                \
    119                                                                             \
    120             out3 = out3 / 30000;                                            \
    121                                                                             \
    122             out4 = ((SRC_SAMPLE(10) + SRC_SAMPLE(-10)) * 306)               \
    123                  + ((SRC_SAMPLE(11) + SRC_SAMPLE(-11)) * 207)               \
    124                  + ((SRC_SAMPLE(12) + SRC_SAMPLE(-12)) * 78);               \
    125                                                                             \
    126             out4 = out4 / 30000;                                            \
    127                                                                             \
    128             out5 = out1 + out2 - out3 - out4;                               \
    129                                                                             \
    130             CHECK_SATURATION16(out5);                                       \
    131             *psBtOut++ = (INT16)out5;                                       \
    132                                                                             \
    133             pS += SRC_CHANNELS;                                             \
    134         }                                                                   \
    135     }
    136 
    137 
    138 ////////////////////////////////////////////////////////////////////////////////////////////////////
    139 //
    140 #define CONVERT_22050_TO_BLUETOOTH(pStart, pEnd)                            \
    141     {                                                                       \
    142         INT32         out1, out2, out3, out4, out5;                         \
    143         SRC_TYPE    *pS = (SRC_TYPE *)pStart;                               \
    144         SRC_TYPE    *pSEnd = (SRC_TYPE *)pEnd;                              \
    145                                                                             \
    146         while (pS < pSEnd)                                                  \
    147         {                                                                   \
    148             CurrentPos -= 8000;                                             \
    149                                                                             \
    150             if (CurrentPos >= 0)                                            \
    151             {                                                               \
    152                 pS += SRC_CHANNELS;                                         \
    153                 continue;                                                   \
    154             }                                                               \
    155             CurrentPos += dwSrcSps;                                         \
    156                                                                             \
    157             out1 = (SRC_SAMPLE(0) * 2993)                                   \
    158                  + ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 2568)                \
    159                  + ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1509)                \
    160                  + ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 331);                \
    161                                                                             \
    162             out1 = out1 / 30000;                                            \
    163                                                                             \
    164             out2 = ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 454)                 \
    165                  + ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 620)                 \
    166                  + ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 305);                \
    167                                                                             \
    168             out2 = out2 / 30000;                                            \
    169                                                                             \
    170             out3 = ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 127)                 \
    171                  + ((SRC_SAMPLE(8) + SRC_SAMPLE(-8)) * 350)                 \
    172                  + ((SRC_SAMPLE(9) + SRC_SAMPLE(-9)) * 265)                 \
    173                  + ((SRC_SAMPLE(10) + SRC_SAMPLE(-10)) * 6);                \
    174                                                                             \
    175             out3 = out3 / 30000;                                            \
    176                                                                             \
    177             out4 = ((SRC_SAMPLE(11) + SRC_SAMPLE(-11)) * 201);              \
    178                                                                             \
    179             out4 = out4 / 30000;                                            \
    180                                                                             \
    181             out5 = out1 - out2 + out3 - out4;                               \
    182                                                                             \
    183             CHECK_SATURATION16(out5);                                       \
    184             *psBtOut++ = (INT16)out5;                                       \
    185                                                                             \
    186             pS += SRC_CHANNELS;                                             \
    187         }                                                                   \
    188     }
    189 
    190 
    191 ////////////////////////////////////////////////////////////////////////////////////////////////////
    192 //
    193 #define CONVERT_11025_TO_BLUETOOTH(pStart, pEnd)                            \
    194     {                                                                       \
    195         INT32         out1;                                                   \
    196         SRC_TYPE    *pS = (SRC_TYPE *)pStart;                               \
    197         SRC_TYPE    *pSEnd = (SRC_TYPE *)pEnd;                              \
    198                                                                             \
    199         while (pS < pSEnd)                                                  \
    200         {                                                                   \
    201             CurrentPos -= 8000;                                             \
    202                                                                             \
    203             if (CurrentPos >= 0)                                            \
    204             {                                                               \
    205                 pS += SRC_CHANNELS;                                         \
    206                 continue;                                                   \
    207             }                                                               \
    208             CurrentPos += dwSrcSps;                                         \
    209                                                                             \
    210             out1 = (SRC_SAMPLE(0) * 6349)                                   \
    211                  + ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 2874)                \
    212                  - ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1148)                \
    213                  - ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 287)                 \
    214                  + ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 675)                 \
    215                  - ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 258)                 \
    216                  - ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 206)                 \
    217                  + ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 266);                \
    218                                                                             \
    219             out1 = out1 / 30000;                                            \
    220                                                                             \
    221             CHECK_SATURATION16(out1);                                       \
    222             *psBtOut++ = (INT16)out1;                                       \
    223                                                                             \
    224             pS += SRC_CHANNELS;                                             \
    225         }                                                                   \
    226     }
    227 
    228 
    229 ////////////////////////////////////////////////////////////////////////////////////////////////////
    230 //
    231 #undef  SRC_CHANNELS
    232 #undef  SRC_SAMPLE
    233 #undef  SRC_TYPE
    234 
    235 #define SRC_TYPE        UINT8
    236 #define SRC_CHANNELS    1
    237 #define SRC_SAMPLE(x)   ((pS[x]  - 0x80) << 8)
    238 
    239 /*****************************************************************************
    240 **  Local Function
    241 *****************************************************************************/
    242 INT32 Convert_8M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
    243                     UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
    244 {
    245     INT32             CurrentPos = *pLastCurPos;
    246     SRC_TYPE        *pIn, *pInEnd;
    247     SRC_TYPE        *pOv, *pOvEnd;
    248     INT16           *psBtOut = (INT16 *)pDst;
    249 #if BTA_DM_SCO_DEBUG
    250     APPL_TRACE_DEBUG("Convert_8M_ToBT_Filtered,  CurrentPos %d\n", CurrentPos);
    251 #endif
    252     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
    253 
    254     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
    255 	pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
    256 
    257     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
    258 	pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
    259         BTA_DM_PCM_OVERLAP_SIZE);
    260 
    261     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100)
    262     {
    263         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
    264         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
    265     }
    266     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050)
    267     {
    268         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
    269         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
    270     }
    271     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025)
    272     {
    273         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
    274         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
    275     }
    276 
    277     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
    278         (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
    279 
    280     *pLastCurPos = CurrentPos;
    281 
    282     return (psBtOut - (INT16 *)pDst);
    283 }
    284 
    285 INT32 Convert_8M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
    286 {
    287     INT32             CurrentPos;
    288     UINT8            *pbSrc = (UINT8 *)pSrc;
    289     INT16           *psDst = (INT16 *)pDst;
    290     INT16           sWorker;
    291 
    292     //      start at dwSpsSrc / 2, decrement by 8000
    293     //
    294     CurrentPos = (dwSrcSps >> 1);
    295 
    296     while (dwSrcSamples--)
    297     {
    298         CurrentPos -= 8000;
    299 
    300         if (CurrentPos >= 0)
    301             pbSrc++;
    302         else
    303         {
    304             sWorker = *pbSrc++;
    305             sWorker -= 0x80;
    306             sWorker <<= 8;
    307 
    308             *psDst++ = sWorker;
    309 
    310             CurrentPos += dwSrcSps;
    311         }
    312     }
    313 
    314     return (psDst - (INT16 *)pDst);
    315 }
    316 
    317 
    318 ////////////////////////////////////////////////////////////////////////////////////////////////////
    319 //
    320 #undef  SRC_CHANNELS
    321 #undef  SRC_SAMPLE
    322 #undef  SRC_TYPE
    323 
    324 #define SRC_TYPE        INT16
    325 #define SRC_CHANNELS    1
    326 #define SRC_SAMPLE(x)   pS[x]
    327 
    328 INT32 Convert_16M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
    329                                  UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
    330 {
    331     INT32             CurrentPos = *pLastCurPos;
    332     SRC_TYPE        *pIn, *pInEnd;
    333     SRC_TYPE        *pOv, *pOvEnd;
    334     INT16           *psBtOut = (INT16 *)pDst;
    335 
    336     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
    337 
    338     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
    339 	pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
    340 
    341     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
    342 	pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
    343 
    344     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100)
    345     {
    346         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
    347         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
    348     }
    349     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050)
    350     {
    351         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
    352         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
    353     }
    354     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025)
    355     {
    356         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
    357         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
    358     }
    359 
    360     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
    361         (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
    362 
    363     *pLastCurPos = CurrentPos;
    364 
    365     return (psBtOut - (INT16 *)pDst);
    366 }
    367 
    368 INT32 Convert_16M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
    369 {
    370     INT32             CurrentPos;
    371     INT16           *psSrc = (INT16 *)pSrc;
    372     INT16           *psDst = (INT16 *)pDst;
    373 
    374     //      start at dwSpsSrc / 2, decrement by 8000
    375     //
    376     CurrentPos = (dwSrcSps >> 1);
    377 
    378     while (dwSrcSamples--)
    379     {
    380         CurrentPos -= 8000;
    381 
    382         if (CurrentPos >= 0)
    383             psSrc++;
    384         else
    385         {
    386             *psDst++ = *psSrc++;
    387 
    388             CurrentPos += dwSrcSps;
    389         }
    390     }
    391 
    392     return (psDst - (INT16 *)pDst);
    393 }
    394 
    395 ////////////////////////////////////////////////////////////////////////////////////////////////////
    396 //
    397 #undef  SRC_CHANNELS
    398 #undef  SRC_SAMPLE
    399 #undef  SRC_TYPE
    400 
    401 #define SRC_TYPE        UINT8
    402 #define SRC_CHANNELS    2
    403 #define SRC_SAMPLE(x) ((((pS[x * 2]  - 0x80) << 8) + ((pS[(x * 2) + 1]  - 0x80) << 8)) >> 1)
    404 
    405 INT32 Convert_8S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
    406                                 UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
    407 {
    408     INT32             CurrentPos = *pLastCurPos;
    409     SRC_TYPE        *pIn, *pInEnd;
    410     SRC_TYPE        *pOv, *pOvEnd;
    411     INT16           *psBtOut = (INT16 *)pDst;
    412 
    413 #if BTA_DM_SCO_DEBUG
    414     APPL_TRACE_DEBUG("Convert_8S_ToBT_Filtered CurrentPos %d, SRC_TYPE %d, SRC_CHANNELS %d, \
    415         dwSrcSamples %d,  dwSrcSps %d",  	CurrentPos, sizeof (SRC_TYPE), SRC_CHANNELS, \
    416         dwSrcSamples, dwSrcSps);
    417 #endif
    418     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
    419 
    420     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
    421 	pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
    422 
    423     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
    424 	pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
    425 
    426     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100)
    427     {
    428         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
    429         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
    430     }
    431     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050)
    432     {
    433         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
    434         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
    435     }
    436     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025)
    437     {
    438         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
    439         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
    440     }
    441 
    442     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
    443         (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
    444 
    445     *pLastCurPos = CurrentPos;
    446 
    447     return (psBtOut - (INT16 *)pDst);
    448 }
    449 
    450 INT32 Convert_8S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
    451 {
    452     INT32             CurrentPos;
    453     UINT8            *pbSrc = (UINT8 *)pSrc;
    454     INT16           *psDst = (INT16 *)pDst;
    455     INT16           sWorker, sWorker2;
    456 
    457     //      start at dwSpsSrc / 2, decrement by 8000
    458     //
    459     CurrentPos = (dwSrcSps >> 1);
    460 
    461     while (dwSrcSamples--)
    462     {
    463         CurrentPos -= 8000;
    464 
    465         if (CurrentPos >= 0)
    466             pbSrc += 2;
    467         else
    468         {
    469             sWorker = *(unsigned char *)pbSrc;
    470             sWorker -= 0x80;
    471             sWorker <<= 8;
    472             pbSrc++;
    473 
    474             sWorker2 = *(unsigned char *)pbSrc;
    475             sWorker2 -= 0x80;
    476             sWorker2 <<= 8;
    477             pbSrc++;
    478 
    479             sWorker += sWorker2;
    480             sWorker >>= 1;
    481 
    482             *psDst++ = sWorker;
    483 
    484             CurrentPos += dwSrcSps;
    485         }
    486     }
    487 
    488     return (psDst - (INT16 *)pDst);
    489 }
    490 
    491 
    492 ////////////////////////////////////////////////////////////////////////////////////////////////////
    493 //
    494 #undef  SRC_CHANNELS
    495 #undef  SRC_SAMPLE
    496 #undef  SRC_TYPE
    497 
    498 #define SRC_TYPE        INT16
    499 #define SRC_CHANNELS    2
    500 #define SRC_SAMPLE(x) ((pS[x * 2] + pS[(x * 2) + 1]) >> 1)
    501 
    502 INT32 Convert_16S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
    503                                  UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
    504 {
    505     INT32             CurrentPos = *pLastCurPos;
    506     SRC_TYPE        *pIn, *pInEnd;
    507     SRC_TYPE        *pOv, *pOvEnd;
    508     INT16           *psBtOut = (INT16 *)pDst;
    509 
    510     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
    511 
    512     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
    513 	pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
    514 
    515     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
    516 	pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
    517 
    518     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100)
    519     {
    520         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
    521         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
    522     }
    523     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050)
    524     {
    525         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
    526         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
    527     }
    528     else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025)
    529     {
    530         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
    531         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
    532     }
    533 
    534     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
    535         (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
    536 
    537     *pLastCurPos = CurrentPos;
    538 
    539     return (psBtOut - (INT16 *)pDst);
    540 }
    541 
    542 INT32 Convert_16S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
    543 {
    544     INT32             CurrentPos;
    545     INT16           *psSrc = (INT16 *)pSrc;
    546     INT16           *psDst = (INT16 *)pDst;
    547     INT16           sWorker;
    548 
    549     //      start at dwSpsSrc / 2, decrement by 8000
    550     //
    551     CurrentPos = (dwSrcSps >> 1);
    552 
    553     while (dwSrcSamples--)
    554     {
    555         CurrentPos -= 8000;
    556 
    557         if (CurrentPos >= 0)
    558             psSrc += 2;
    559         else
    560         {
    561             /* CR 82894, to avoid overflow, divide before add */
    562             sWorker  = ((*psSrc) >> 1 );
    563             psSrc++;
    564             sWorker += ((*psSrc) >> 1 );
    565             psSrc++;
    566 
    567             *psDst++ = sWorker;
    568 
    569             CurrentPos += dwSrcSps;
    570         }
    571     }
    572 
    573     return (psDst - (INT16 *)pDst);
    574 }
    575 
    576 /*******************************************************************************
    577 **
    578 ** Function         BTA_DmPcmInitSamples
    579 **
    580 ** Description      initialize the down sample converter.
    581 **
    582 **                  src_sps: original samples per second (source audio data)
    583 **                            (ex. 44100, 48000)
    584 **                  bits: number of bits per pcm sample (16)
    585 **                  n_channels: number of channels (i.e. mono(1), stereo(2)...)
    586 **
    587 ** Returns          none
    588 **
    589 *******************************************************************************/
    590 void BTA_DmPcmInitSamples (UINT32 src_sps, UINT32 bits, UINT32 n_channels)
    591 {
    592     tBTA_DM_PCM_RESAMPLE_CB *p_cb = &bta_dm_pcm_cb;
    593 
    594     p_cb->cur_pos       = src_sps / 2;
    595     p_cb->src_sps       = src_sps;
    596     p_cb->bits          = bits;
    597     p_cb->n_channels    = n_channels;
    598     p_cb->sample_size   = 2;
    599     p_cb->divisor	    = 2;
    600 
    601     memset(p_cb->overlap_area, 0, sizeof(p_cb->overlap_area) );
    602 
    603     if ((src_sps == BTA_DM_PCM_SMPL_RATE_44100) ||
    604         (src_sps == BTA_DM_PCM_SMPL_RATE_22050) ||
    605         (src_sps == BTA_DM_PCM_SMPL_RATE_11025))
    606          p_cb->can_be_filtered = 1;
    607     else
    608          p_cb->can_be_filtered = 0;
    609 
    610 #if BTA_DM_SCO_DEBUG
    611     APPL_TRACE_DEBUG("bta_dm_pcm_init_samples: n_channels = %d bits = %d", n_channels, bits);
    612 #endif
    613     if(n_channels == 1)
    614     {
    615         /* mono */
    616         if(bits == 8)
    617         {
    618             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8M_ToBT_Filtered;
    619             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8M_ToBT_NoFilter;
    620 	        p_cb->divisor	 = 1;
    621         }
    622         else
    623         {
    624             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16M_ToBT_Filtered;
    625             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16M_ToBT_NoFilter;
    626         }
    627     }
    628     else
    629     {
    630         /* stereo */
    631         if(bits == 8)
    632         {
    633             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8S_ToBT_Filtered;
    634             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8S_ToBT_NoFilter;
    635         }
    636         else
    637         {
    638             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16S_ToBT_Filtered;
    639             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16S_ToBT_NoFilter;
    640 	        p_cb->divisor	 = 4;
    641         }
    642     }
    643 
    644 #if BTA_DM_SCO_DEBUG
    645     APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: cur_pos %d, src_sps %d", \
    646 		p_cb->cur_pos, p_cb->src_sps);
    647     APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: bits %d, n_channels %d, sample_size %d, ", \
    648 		p_cb->bits, p_cb->n_channels, p_cb->sample_size);
    649     APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: can_be_filtered %d, n_channels: %d, \
    650         divisor %d", p_cb->can_be_filtered, p_cb->n_channels, p_cb->divisor);
    651 #endif
    652 
    653 }
    654 
    655 /**************************************************************************************
    656 ** Function         BTA_DmPcmResample
    657 **
    658 ** Description      Down sampling utility to convert higher sampling rate into 8K/16bits
    659 **                  PCM samples.
    660 **
    661 ** Parameters       p_src: pointer to the buffer where the original sampling PCM
    662 **                              are stored.
    663 **                  in_bytes:  Length of the input PCM sample buffer in byte.
    664 **                  p_dst:      pointer to the buffer which is to be used to store
    665 **                              the converted PCM samples.
    666 **
    667 **
    668 ** Returns          INT32: number of samples converted.
    669 **
    670 **************************************************************************************/
    671 INT32 BTA_DmPcmResample (void *p_src, UINT32 in_bytes, void *p_dst)
    672 {
    673     UINT32 out_sample;
    674 
    675 #if BTA_DM_SCO_DEBUG
    676     APPL_TRACE_DEBUG("bta_pcm_resample : insamples  %d",  (in_bytes  / bta_dm_pcm_cb.divisor));
    677 #endif
    678     if(bta_dm_pcm_cb.can_be_filtered)
    679     {
    680         out_sample = (*bta_dm_pcm_cb.filter) (p_src, p_dst, (in_bytes  / bta_dm_pcm_cb.divisor),
    681             bta_dm_pcm_cb.src_sps, (INT32 *) &bta_dm_pcm_cb.cur_pos, bta_dm_pcm_cb.overlap_area);
    682     }
    683     else
    684     {
    685         out_sample = (*bta_dm_pcm_cb.nofilter) (p_src, p_dst,
    686             (in_bytes / bta_dm_pcm_cb.divisor), bta_dm_pcm_cb.src_sps);
    687     }
    688 
    689 #if BTA_DM_SCO_DEBUG
    690     APPL_TRACE_DEBUG("bta_pcm_resample : outsamples  %d",  out_sample);
    691 #endif
    692 
    693     return (out_sample * bta_dm_pcm_cb.sample_size);
    694 }
    695 #endif
    696