primitives.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "audio/android/cutils/bitops.h" /* for popcount() */
  17. #include "audio/android/audio_utils/include/audio_utils/primitives.h"
  18. #include "audio/android/audio_utils/private/private.h"
  19. void ditherAndClamp(int32_t* out, const int32_t *sums, size_t c)
  20. {
  21. size_t i;
  22. for (i=0 ; i<c ; i++) {
  23. int32_t l = *sums++;
  24. int32_t r = *sums++;
  25. int32_t nl = l >> 12;
  26. int32_t nr = r >> 12;
  27. l = clamp16(nl);
  28. r = clamp16(nr);
  29. *out++ = (r<<16) | (l & 0xFFFF);
  30. }
  31. }
  32. void memcpy_to_i16_from_u8(int16_t *dst, const uint8_t *src, size_t count)
  33. {
  34. dst += count;
  35. src += count;
  36. while (count--) {
  37. *--dst = (int16_t)(*--src - 0x80) << 8;
  38. }
  39. }
  40. void memcpy_to_u8_from_i16(uint8_t *dst, const int16_t *src, size_t count)
  41. {
  42. while (count--) {
  43. *dst++ = (*src++ >> 8) + 0x80;
  44. }
  45. }
  46. void memcpy_to_u8_from_float(uint8_t *dst, const float *src, size_t count)
  47. {
  48. while (count--) {
  49. *dst++ = clamp8_from_float(*src++);
  50. }
  51. }
  52. void memcpy_to_i16_from_i32(int16_t *dst, const int32_t *src, size_t count)
  53. {
  54. while (count--) {
  55. *dst++ = *src++ >> 16;
  56. }
  57. }
  58. void memcpy_to_i16_from_float(int16_t *dst, const float *src, size_t count)
  59. {
  60. while (count--) {
  61. *dst++ = clamp16_from_float(*src++);
  62. }
  63. }
  64. void memcpy_to_float_from_q4_27(float *dst, const int32_t *src, size_t count)
  65. {
  66. while (count--) {
  67. *dst++ = float_from_q4_27(*src++);
  68. }
  69. }
  70. void memcpy_to_float_from_i16(float *dst, const int16_t *src, size_t count)
  71. {
  72. while (count--) {
  73. *dst++ = float_from_i16(*src++);
  74. }
  75. }
  76. void memcpy_to_float_from_u8(float *dst, const uint8_t *src, size_t count)
  77. {
  78. while (count--) {
  79. *dst++ = float_from_u8(*src++);
  80. }
  81. }
  82. void memcpy_to_float_from_p24(float *dst, const uint8_t *src, size_t count)
  83. {
  84. while (count--) {
  85. *dst++ = float_from_p24(src);
  86. src += 3;
  87. }
  88. }
  89. void memcpy_to_i16_from_p24(int16_t *dst, const uint8_t *src, size_t count)
  90. {
  91. while (count--) {
  92. #ifdef HAVE_BIG_ENDIAN
  93. *dst++ = src[1] | (src[0] << 8);
  94. #else
  95. *dst++ = src[1] | (src[2] << 8);
  96. #endif
  97. src += 3;
  98. }
  99. }
  100. void memcpy_to_i32_from_p24(int32_t *dst, const uint8_t *src, size_t count)
  101. {
  102. while (count--) {
  103. #ifdef HAVE_BIG_ENDIAN
  104. *dst++ = (src[2] << 8) | (src[1] << 16) | (src[0] << 24);
  105. #else
  106. *dst++ = (src[0] << 8) | (src[1] << 16) | (src[2] << 24);
  107. #endif
  108. src += 3;
  109. }
  110. }
  111. void memcpy_to_p24_from_i16(uint8_t *dst, const int16_t *src, size_t count)
  112. {
  113. while (count--) {
  114. #ifdef HAVE_BIG_ENDIAN
  115. *dst++ = *src >> 8;
  116. *dst++ = *src++;
  117. *dst++ = 0;
  118. #else
  119. *dst++ = 0;
  120. *dst++ = *src;
  121. *dst++ = *src++ >> 8;
  122. #endif
  123. }
  124. }
  125. void memcpy_to_p24_from_float(uint8_t *dst, const float *src, size_t count)
  126. {
  127. while (count--) {
  128. int32_t ival = clamp24_from_float(*src++);
  129. #ifdef HAVE_BIG_ENDIAN
  130. *dst++ = ival >> 16;
  131. *dst++ = ival >> 8;
  132. *dst++ = ival;
  133. #else
  134. *dst++ = ival;
  135. *dst++ = ival >> 8;
  136. *dst++ = ival >> 16;
  137. #endif
  138. }
  139. }
  140. void memcpy_to_p24_from_q8_23(uint8_t *dst, const int32_t *src, size_t count)
  141. {
  142. while (count--) {
  143. int32_t ival = clamp24_from_q8_23(*src++);
  144. #ifdef HAVE_BIG_ENDIAN
  145. *dst++ = ival >> 16;
  146. *dst++ = ival >> 8;
  147. *dst++ = ival;
  148. #else
  149. *dst++ = ival;
  150. *dst++ = ival >> 8;
  151. *dst++ = ival >> 16;
  152. #endif
  153. }
  154. }
  155. void memcpy_to_p24_from_i32(uint8_t *dst, const int32_t *src, size_t count)
  156. {
  157. while (count--) {
  158. int32_t ival = *src++ >> 8;
  159. #ifdef HAVE_BIG_ENDIAN
  160. *dst++ = ival >> 16;
  161. *dst++ = ival >> 8;
  162. *dst++ = ival;
  163. #else
  164. *dst++ = ival;
  165. *dst++ = ival >> 8;
  166. *dst++ = ival >> 16;
  167. #endif
  168. }
  169. }
  170. void memcpy_to_q8_23_from_i16(int32_t *dst, const int16_t *src, size_t count)
  171. {
  172. while (count--) {
  173. *dst++ = (int32_t)*src++ << 8;
  174. }
  175. }
  176. void memcpy_to_q8_23_from_float_with_clamp(int32_t *dst, const float *src, size_t count)
  177. {
  178. while (count--) {
  179. *dst++ = clamp24_from_float(*src++);
  180. }
  181. }
  182. void memcpy_to_q8_23_from_p24(int32_t *dst, const uint8_t *src, size_t count)
  183. {
  184. while (count--) {
  185. #ifdef HAVE_BIG_ENDIAN
  186. *dst++ = (int8_t)src[0] << 16 | src[1] << 8 | src[2];
  187. #else
  188. *dst++ = (int8_t)src[2] << 16 | src[1] << 8 | src[0];
  189. #endif
  190. src += 3;
  191. }
  192. }
  193. void memcpy_to_q4_27_from_float(int32_t *dst, const float *src, size_t count)
  194. {
  195. while (count--) {
  196. *dst++ = clampq4_27_from_float(*src++);
  197. }
  198. }
  199. void memcpy_to_i16_from_q8_23(int16_t *dst, const int32_t *src, size_t count)
  200. {
  201. while (count--) {
  202. *dst++ = clamp16(*src++ >> 8);
  203. }
  204. }
  205. void memcpy_to_float_from_q8_23(float *dst, const int32_t *src, size_t count)
  206. {
  207. while (count--) {
  208. *dst++ = float_from_q8_23(*src++);
  209. }
  210. }
  211. void memcpy_to_i32_from_i16(int32_t *dst, const int16_t *src, size_t count)
  212. {
  213. while (count--) {
  214. *dst++ = (int32_t)*src++ << 16;
  215. }
  216. }
  217. void memcpy_to_i32_from_float(int32_t *dst, const float *src, size_t count)
  218. {
  219. while (count--) {
  220. *dst++ = clamp32_from_float(*src++);
  221. }
  222. }
  223. void memcpy_to_float_from_i32(float *dst, const int32_t *src, size_t count)
  224. {
  225. while (count--) {
  226. *dst++ = float_from_i32(*src++);
  227. }
  228. }
  229. void downmix_to_mono_i16_from_stereo_i16(int16_t *dst, const int16_t *src, size_t count)
  230. {
  231. while (count--) {
  232. *dst++ = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
  233. src += 2;
  234. }
  235. }
  236. void upmix_to_stereo_i16_from_mono_i16(int16_t *dst, const int16_t *src, size_t count)
  237. {
  238. while (count--) {
  239. int32_t temp = *src++;
  240. dst[0] = temp;
  241. dst[1] = temp;
  242. dst += 2;
  243. }
  244. }
  245. void downmix_to_mono_float_from_stereo_float(float *dst, const float *src, size_t frames)
  246. {
  247. while (frames--) {
  248. *dst++ = (src[0] + src[1]) * 0.5;
  249. src += 2;
  250. }
  251. }
  252. void upmix_to_stereo_float_from_mono_float(float *dst, const float *src, size_t frames)
  253. {
  254. while (frames--) {
  255. float temp = *src++;
  256. dst[0] = temp;
  257. dst[1] = temp;
  258. dst += 2;
  259. }
  260. }
  261. size_t nonZeroMono32(const int32_t *samples, size_t count)
  262. {
  263. size_t nonZero = 0;
  264. while (count-- > 0) {
  265. if (*samples++ != 0) {
  266. nonZero++;
  267. }
  268. }
  269. return nonZero;
  270. }
  271. size_t nonZeroMono16(const int16_t *samples, size_t count)
  272. {
  273. size_t nonZero = 0;
  274. while (count-- > 0) {
  275. if (*samples++ != 0) {
  276. nonZero++;
  277. }
  278. }
  279. return nonZero;
  280. }
  281. size_t nonZeroStereo32(const int32_t *frames, size_t count)
  282. {
  283. size_t nonZero = 0;
  284. while (count-- > 0) {
  285. if (frames[0] != 0 || frames[1] != 0) {
  286. nonZero++;
  287. }
  288. frames += 2;
  289. }
  290. return nonZero;
  291. }
  292. size_t nonZeroStereo16(const int16_t *frames, size_t count)
  293. {
  294. size_t nonZero = 0;
  295. while (count-- > 0) {
  296. if (frames[0] != 0 || frames[1] != 0) {
  297. nonZero++;
  298. }
  299. frames += 2;
  300. }
  301. return nonZero;
  302. }
  303. /*
  304. * C macro to do channel mask copying independent of dst/src sample type.
  305. * Don't pass in any expressions for the macro arguments here.
  306. */
  307. #define copy_frame_by_mask(dst, dmask, src, smask, count, zero) \
  308. { \
  309. uint32_t bit, ormask; \
  310. while ((count)--) { \
  311. ormask = (dmask) | (smask); \
  312. while (ormask) { \
  313. bit = ormask & -ormask; /* get lowest bit */ \
  314. ormask ^= bit; /* remove lowest bit */ \
  315. if ((dmask) & bit) { \
  316. *(dst)++ = (smask) & bit ? *(src)++ : (zero); \
  317. } else { /* source channel only */ \
  318. ++(src); \
  319. } \
  320. } \
  321. } \
  322. }
  323. void memcpy_by_channel_mask(void *dst, uint32_t dst_mask,
  324. const void *src, uint32_t src_mask, size_t sample_size, size_t count)
  325. {
  326. #if 0
  327. /* alternate way of handling memcpy_by_channel_mask by using the idxary */
  328. int8_t idxary[32];
  329. uint32_t src_channels = popcount(src_mask);
  330. uint32_t dst_channels =
  331. memcpy_by_index_array_initialization(idxary, 32, dst_mask, src_mask);
  332. memcpy_by_idxary(dst, dst_channels, src, src_channels, idxary, sample_size, count);
  333. #else
  334. if (dst_mask == src_mask) {
  335. memcpy(dst, src, sample_size * popcount(dst_mask) * count);
  336. return;
  337. }
  338. switch (sample_size) {
  339. case 1: {
  340. uint8_t *udst = (uint8_t*)dst;
  341. const uint8_t *usrc = (const uint8_t*)src;
  342. copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, 0);
  343. } break;
  344. case 2: {
  345. uint16_t *udst = (uint16_t*)dst;
  346. const uint16_t *usrc = (const uint16_t*)src;
  347. copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, 0);
  348. } break;
  349. case 3: { /* could be slow. use a struct to represent 3 bytes of data. */
  350. uint8x3_t *udst = (uint8x3_t*)dst;
  351. const uint8x3_t *usrc = (const uint8x3_t*)src;
  352. static const uint8x3_t zero; /* tricky - we use this to zero out a sample */
  353. copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, zero);
  354. } break;
  355. case 4: {
  356. uint32_t *udst = (uint32_t*)dst;
  357. const uint32_t *usrc = (const uint32_t*)src;
  358. copy_frame_by_mask(udst, dst_mask, usrc, src_mask, count, 0);
  359. } break;
  360. default:
  361. abort(); /* illegal value */
  362. break;
  363. }
  364. #endif
  365. }
  366. /*
  367. * C macro to do copying by index array, to rearrange samples
  368. * within a frame. This is independent of src/dst sample type.
  369. * Don't pass in any expressions for the macro arguments here.
  370. */
  371. #define copy_frame_by_idx(dst, dst_channels, src, src_channels, idxary, count, zero) \
  372. { \
  373. unsigned i; \
  374. int index; \
  375. while ((count)--) { \
  376. for (i = 0; i < (dst_channels); ++i) { \
  377. index = (idxary)[i]; \
  378. *(dst)++ = index < 0 ? (zero) : (src)[index]; \
  379. } \
  380. (src) += (src_channels); \
  381. } \
  382. }
  383. void memcpy_by_index_array(void *dst, uint32_t dst_channels,
  384. const void *src, uint32_t src_channels,
  385. const int8_t *idxary, size_t sample_size, size_t count)
  386. {
  387. switch (sample_size) {
  388. case 1: {
  389. uint8_t *udst = (uint8_t*)dst;
  390. const uint8_t *usrc = (const uint8_t*)src;
  391. copy_frame_by_idx(udst, dst_channels, usrc, src_channels, idxary, count, 0);
  392. } break;
  393. case 2: {
  394. uint16_t *udst = (uint16_t*)dst;
  395. const uint16_t *usrc = (const uint16_t*)src;
  396. copy_frame_by_idx(udst, dst_channels, usrc, src_channels, idxary, count, 0);
  397. } break;
  398. case 3: { /* could be slow. use a struct to represent 3 bytes of data. */
  399. uint8x3_t *udst = (uint8x3_t*)dst;
  400. const uint8x3_t *usrc = (const uint8x3_t*)src;
  401. static const uint8x3_t zero;
  402. copy_frame_by_idx(udst, dst_channels, usrc, src_channels, idxary, count, zero);
  403. } break;
  404. case 4: {
  405. uint32_t *udst = (uint32_t*)dst;
  406. const uint32_t *usrc = (const uint32_t*)src;
  407. copy_frame_by_idx(udst, dst_channels, usrc, src_channels, idxary, count, 0);
  408. } break;
  409. default:
  410. abort(); /* illegal value */
  411. break;
  412. }
  413. }
  414. size_t memcpy_by_index_array_initialization(int8_t *idxary, size_t idxcount,
  415. uint32_t dst_mask, uint32_t src_mask)
  416. {
  417. size_t n = 0;
  418. int srcidx = 0;
  419. uint32_t bit, ormask = src_mask | dst_mask;
  420. while (ormask && n < idxcount) {
  421. bit = ormask & -ormask; /* get lowest bit */
  422. ormask ^= bit; /* remove lowest bit */
  423. if (src_mask & dst_mask & bit) { /* matching channel */
  424. idxary[n++] = srcidx++;
  425. } else if (src_mask & bit) { /* source channel only */
  426. ++srcidx;
  427. } else { /* destination channel only */
  428. idxary[n++] = -1;
  429. }
  430. }
  431. return n + popcount(ormask & dst_mask);
  432. }
  433. size_t memcpy_by_index_array_initialization_src_index(int8_t *idxary, size_t idxcount,
  434. uint32_t dst_mask, uint32_t src_mask) {
  435. size_t dst_count = popcount(dst_mask);
  436. if (idxcount == 0) {
  437. return dst_count;
  438. }
  439. if (dst_count > idxcount) {
  440. dst_count = idxcount;
  441. }
  442. size_t src_idx, dst_idx;
  443. for (src_idx = 0, dst_idx = 0; dst_idx < dst_count; ++dst_idx) {
  444. if (src_mask & 1) {
  445. idxary[dst_idx] = src_idx++;
  446. } else {
  447. idxary[dst_idx] = -1;
  448. }
  449. src_mask >>= 1;
  450. }
  451. return dst_idx;
  452. }
  453. size_t memcpy_by_index_array_initialization_dst_index(int8_t *idxary, size_t idxcount,
  454. uint32_t dst_mask, uint32_t src_mask) {
  455. size_t src_idx, dst_idx;
  456. size_t dst_count = __builtin_popcount(dst_mask);
  457. size_t src_count = __builtin_popcount(src_mask);
  458. if (idxcount == 0) {
  459. return dst_count;
  460. }
  461. if (dst_count > idxcount) {
  462. dst_count = idxcount;
  463. }
  464. for (src_idx = 0, dst_idx = 0; dst_idx < dst_count; ++src_idx) {
  465. if (dst_mask & 1) {
  466. idxary[dst_idx++] = src_idx < src_count ? (signed)src_idx : -1;
  467. }
  468. dst_mask >>= 1;
  469. }
  470. return dst_idx;
  471. }