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