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
51typedef INT32   (*PCONVERT_TO_BT_FILTERED)  (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
52                             UINT32 dwSrcSps,INT32 *pLastCurPos, UINT8 *pOverlapArea);
53typedef INT32   (*PCONVERT_TO_BT_NOFILTER)  (void *pSrc, void *pDst, UINT32 dwSrcSamples,
54                                             UINT32 dwSrcSps);
55typedef 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
71tBTA_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*****************************************************************************/
242INT32 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
285INT32 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
328INT32 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
368INT32 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
405INT32 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
450INT32 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
502INT32 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
542INT32 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*******************************************************************************/
590void 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**************************************************************************************/
671INT32 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