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