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