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