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