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