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/bta_api.h"
30 #include "bta/bta_sys.h"
31 #include "osi/allocator.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   (*PCONVERT_TO_BT_FILTERED)  (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
53         UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea);
54 typedef INT32   (*PCONVERT_TO_BT_NOFILTER)  (void *pSrc, void *pDst, UINT32 dwSrcSamples,
55         UINT32 dwSrcSps);
56 typedef struct {
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 static tBTA_DM_PCM_RESAMPLE_CB* p_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 *****************************************************************************/
Convert_8M_ToBT_Filtered(UINT8 * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps,INT32 * pLastCurPos,UINT8 * pOverlapArea)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         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
263         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
264     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
265         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
266         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
267     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
268         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
269         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
270     }
271 
272     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
273             (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
274 
275     *pLastCurPos = CurrentPos;
276 
277     return (psBtOut - (INT16 *)pDst);
278 }
279 
Convert_8M_ToBT_NoFilter(void * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps)280 INT32 Convert_8M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
281 {
282     INT32             CurrentPos;
283     UINT8            *pbSrc = (UINT8 *)pSrc;
284     INT16           *psDst = (INT16 *)pDst;
285     INT16           sWorker;
286 
287     //      start at dwSpsSrc / 2, decrement by 8000
288     //
289     CurrentPos = (dwSrcSps >> 1);
290 
291     while (dwSrcSamples--) {
292         CurrentPos -= 8000;
293 
294         if (CurrentPos >= 0) {
295             pbSrc++;
296         } else {
297             sWorker = *pbSrc++;
298             sWorker -= 0x80;
299             sWorker <<= 8;
300 
301             *psDst++ = sWorker;
302 
303             CurrentPos += dwSrcSps;
304         }
305     }
306 
307     return (psDst - (INT16 *)pDst);
308 }
309 
310 
311 ////////////////////////////////////////////////////////////////////////////////////////////////////
312 //
313 #undef  SRC_CHANNELS
314 #undef  SRC_SAMPLE
315 #undef  SRC_TYPE
316 
317 #define SRC_TYPE        INT16
318 #define SRC_CHANNELS    1
319 #define SRC_SAMPLE(x)   pS[x]
320 
Convert_16M_ToBT_Filtered(UINT8 * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps,INT32 * pLastCurPos,UINT8 * pOverlapArea)321 INT32 Convert_16M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
322                                  UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
323 {
324     INT32             CurrentPos = *pLastCurPos;
325     SRC_TYPE        *pIn, *pInEnd;
326     SRC_TYPE        *pOv, *pOvEnd;
327     INT16           *psBtOut = (INT16 *)pDst;
328 
329     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
330 
331     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
332     pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
333 
334     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
335     pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
336 
337     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
338         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
339         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
340     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
341         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
342         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
343     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
344         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
345         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
346     }
347 
348     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
349             (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
350 
351     *pLastCurPos = CurrentPos;
352 
353     return (psBtOut - (INT16 *)pDst);
354 }
355 
Convert_16M_ToBT_NoFilter(void * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps)356 INT32 Convert_16M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
357 {
358     INT32             CurrentPos;
359     INT16           *psSrc = (INT16 *)pSrc;
360     INT16           *psDst = (INT16 *)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 *)pDst);
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////////////////////////////
382 //
383 #undef  SRC_CHANNELS
384 #undef  SRC_SAMPLE
385 #undef  SRC_TYPE
386 
387 #define SRC_TYPE        UINT8
388 #define SRC_CHANNELS    2
389 #define SRC_SAMPLE(x) ((((pS[x * 2]  - 0x80) << 8) + ((pS[(x * 2) + 1]  - 0x80) << 8)) >> 1)
390 
Convert_8S_ToBT_Filtered(UINT8 * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps,INT32 * pLastCurPos,UINT8 * pOverlapArea)391 INT32 Convert_8S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
392                                 UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
393 {
394     INT32             CurrentPos = *pLastCurPos;
395     SRC_TYPE        *pIn, *pInEnd;
396     SRC_TYPE        *pOv, *pOvEnd;
397     INT16           *psBtOut = (INT16 *)pDst;
398 
399 #if BTA_DM_SCO_DEBUG
400     APPL_TRACE_DEBUG("Convert_8S_ToBT_Filtered CurrentPos %d, SRC_TYPE %d, SRC_CHANNELS %d, \
401         dwSrcSamples %d,  dwSrcSps %d",  	CurrentPos, sizeof (SRC_TYPE), SRC_CHANNELS, \
402                      dwSrcSamples, dwSrcSps);
403 #endif
404     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
405 
406     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
407     pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
408 
409     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
410     pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
411 
412     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
413         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
414         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
415     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
416         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
417         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
418     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
419         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
420         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
421     }
422 
423     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
424             (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
425 
426     *pLastCurPos = CurrentPos;
427 
428     return (psBtOut - (INT16 *)pDst);
429 }
430 
Convert_8S_ToBT_NoFilter(void * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps)431 INT32 Convert_8S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
432 {
433     INT32             CurrentPos;
434     UINT8            *pbSrc = (UINT8 *)pSrc;
435     INT16           *psDst = (INT16 *)pDst;
436     INT16           sWorker, sWorker2;
437 
438     //      start at dwSpsSrc / 2, decrement by 8000
439     //
440     CurrentPos = (dwSrcSps >> 1);
441 
442     while (dwSrcSamples--) {
443         CurrentPos -= 8000;
444 
445         if (CurrentPos >= 0) {
446             pbSrc += 2;
447         } else {
448             sWorker = *(unsigned char *)pbSrc;
449             sWorker -= 0x80;
450             sWorker <<= 8;
451             pbSrc++;
452 
453             sWorker2 = *(unsigned char *)pbSrc;
454             sWorker2 -= 0x80;
455             sWorker2 <<= 8;
456             pbSrc++;
457 
458             sWorker += sWorker2;
459             sWorker >>= 1;
460 
461             *psDst++ = sWorker;
462 
463             CurrentPos += dwSrcSps;
464         }
465     }
466 
467     return (psDst - (INT16 *)pDst);
468 }
469 
470 
471 ////////////////////////////////////////////////////////////////////////////////////////////////////
472 //
473 #undef  SRC_CHANNELS
474 #undef  SRC_SAMPLE
475 #undef  SRC_TYPE
476 
477 #define SRC_TYPE        INT16
478 #define SRC_CHANNELS    2
479 #define SRC_SAMPLE(x) ((pS[x * 2] + pS[(x * 2) + 1]) >> 1)
480 
Convert_16S_ToBT_Filtered(UINT8 * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps,INT32 * pLastCurPos,UINT8 * pOverlapArea)481 INT32 Convert_16S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
482                                  UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
483 {
484     INT32             CurrentPos = *pLastCurPos;
485     SRC_TYPE        *pIn, *pInEnd;
486     SRC_TYPE        *pOv, *pOvEnd;
487     INT16           *psBtOut = (INT16 *)pDst;
488 
489     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
490 
491     pOv    = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
492     pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
493 
494     pIn     = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
495     pInEnd  = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
496 
497     if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
498         CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
499         CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
500     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
501         CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
502         CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
503     } else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
504         CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
505         CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
506     }
507 
508     memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
509             (BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
510 
511     *pLastCurPos = CurrentPos;
512 
513     return (psBtOut - (INT16 *)pDst);
514 }
515 
Convert_16S_ToBT_NoFilter(void * pSrc,void * pDst,UINT32 dwSrcSamples,UINT32 dwSrcSps)516 INT32 Convert_16S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
517 {
518     INT32             CurrentPos;
519     INT16           *psSrc = (INT16 *)pSrc;
520     INT16           *psDst = (INT16 *)pDst;
521     INT16           sWorker;
522 
523     //      start at dwSpsSrc / 2, decrement by 8000
524     //
525     CurrentPos = (dwSrcSps >> 1);
526 
527     while (dwSrcSamples--) {
528         CurrentPos -= 8000;
529 
530         if (CurrentPos >= 0) {
531             psSrc += 2;
532         } else {
533             /* CR 82894, to avoid overflow, divide before add */
534             sWorker  = ((*psSrc) >> 1 );
535             psSrc++;
536             sWorker += ((*psSrc) >> 1 );
537             psSrc++;
538 
539             *psDst++ = sWorker;
540 
541             CurrentPos += dwSrcSps;
542         }
543     }
544 
545     return (psDst - (INT16 *)pDst);
546 }
547 
548 /*******************************************************************************
549 **
550 ** Function         BTA_DmPcmInitSamples
551 **
552 ** Description      initialize the down sample converter.
553 **
554 **                  src_sps: original samples per second (source audio data)
555 **                            (ex. 44100, 48000)
556 **                  bits: number of bits per pcm sample (16)
557 **                  n_channels: number of channels (i.e. mono(1), stereo(2)...)
558 **
559 ** Returns          none
560 **
561 *******************************************************************************/
BTA_DmPcmInitSamples(UINT32 src_sps,UINT32 bits,UINT32 n_channels)562 void BTA_DmPcmInitSamples (UINT32 src_sps, UINT32 bits, UINT32 n_channels)
563 {
564     if ((p_bta_dm_pcm_cb = (tBTA_DM_PCM_RESAMPLE_CB *)osi_malloc(sizeof(tBTA_DM_PCM_RESAMPLE_CB))) == NULL) {
565         APPL_TRACE_ERROR("%s malloc failed!", __func__);
566         return;
567     }
568     tBTA_DM_PCM_RESAMPLE_CB *p_cb = p_bta_dm_pcm_cb;
569 
570     p_cb->cur_pos       = src_sps / 2;
571     p_cb->src_sps       = src_sps;
572     p_cb->bits          = bits;
573     p_cb->n_channels    = n_channels;
574     p_cb->sample_size   = 2;
575     p_cb->divisor       = 2;
576 
577     memset(p_cb->overlap_area, 0, sizeof(p_cb->overlap_area) );
578 
579     if ((src_sps == BTA_DM_PCM_SMPL_RATE_44100) ||
580             (src_sps == BTA_DM_PCM_SMPL_RATE_22050) ||
581             (src_sps == BTA_DM_PCM_SMPL_RATE_11025)) {
582         p_cb->can_be_filtered = 1;
583     } else {
584         p_cb->can_be_filtered = 0;
585     }
586 
587 #if BTA_DM_SCO_DEBUG
588     APPL_TRACE_DEBUG("bta_dm_pcm_init_samples: n_channels = %d bits = %d", n_channels, bits);
589 #endif
590     if (n_channels == 1) {
591         /* mono */
592         if (bits == 8) {
593             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8M_ToBT_Filtered;
594             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8M_ToBT_NoFilter;
595             p_cb->divisor    = 1;
596         } else {
597             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16M_ToBT_Filtered;
598             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16M_ToBT_NoFilter;
599         }
600     } else {
601         /* stereo */
602         if (bits == 8) {
603             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8S_ToBT_Filtered;
604             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8S_ToBT_NoFilter;
605         } else {
606             p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16S_ToBT_Filtered;
607             p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16S_ToBT_NoFilter;
608             p_cb->divisor    = 4;
609         }
610     }
611 
612 #if BTA_DM_SCO_DEBUG
613     APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: cur_pos %d, src_sps %d", \
614                      p_cb->cur_pos, p_cb->src_sps);
615     APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: bits %d, n_channels %d, sample_size %d, ", \
616                      p_cb->bits, p_cb->n_channels, p_cb->sample_size);
617     APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: can_be_filtered %d, n_channels: %d, \
618         divisor %d", p_cb->can_be_filtered, p_cb->n_channels, p_cb->divisor);
619 #endif
620 
621 }
622 
623 /*******************************************************************************
624 **
625 ** Function         BTA_DmPcmDeinitSamples
626 **
627 ** Description      Deinitialize the down sample converter.
628 **
629 ** Returns          none
630 **
631 *******************************************************************************/
BTA_DmPcmDeinitSamples(void)632 void BTA_DmPcmDeinitSamples(void) {
633     osi_free(p_bta_dm_pcm_cb);
634     p_bta_dm_pcm_cb = NULL;
635 }
636 
637 /**************************************************************************************
638 ** Function         BTA_DmPcmResample
639 **
640 ** Description      Down sampling utility to convert higher sampling rate into 8K/16bits
641 **                  PCM samples.
642 **
643 ** Parameters       p_src: pointer to the buffer where the original sampling PCM
644 **                              are stored.
645 **                  in_bytes:  Length of the input PCM sample buffer in byte.
646 **                  p_dst:      pointer to the buffer which is to be used to store
647 **                              the converted PCM samples.
648 **
649 **
650 ** Returns          INT32: number of samples converted.
651 **
652 **************************************************************************************/
BTA_DmPcmResample(void * p_src,UINT32 in_bytes,void * p_dst)653 INT32 BTA_DmPcmResample (void *p_src, UINT32 in_bytes, void *p_dst)
654 {
655     UINT32 out_sample;
656 
657 #if BTA_DM_SCO_DEBUG
658     APPL_TRACE_DEBUG("bta_pcm_resample : insamples  %d",  (in_bytes  / p_bta_dm_pcm_cb->divisor));
659 #endif
660     if (p_bta_dm_pcm_cb->can_be_filtered) {
661         out_sample = (*p_bta_dm_pcm_cb->filter) (p_src, p_dst, (in_bytes  / p_bta_dm_pcm_cb->divisor),
662                                               p_bta_dm_pcm_cb->src_sps, (INT32 *) &(p_bta_dm_pcm_cb->cur_pos), p_bta_dm_pcm_cb->overlap_area);
663     } else {
664         out_sample = (*p_bta_dm_pcm_cb->nofilter) (p_src, p_dst,
665                                                 (in_bytes / p_bta_dm_pcm_cb->divisor), p_bta_dm_pcm_cb->src_sps);
666     }
667 
668 #if BTA_DM_SCO_DEBUG
669     APPL_TRACE_DEBUG("bta_pcm_resample : outsamples  %d",  out_sample);
670 #endif
671 
672     return (out_sample);
673 }
674 #endif
675