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 *****************************************************************************/ 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 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 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 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 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 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 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 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 *******************************************************************************/ 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 **************************************************************************************/ 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