bta_dm_sco.c 29 KB

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