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