output_pack.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /*
  2. * Squeezelite - lightweight headless squeezebox emulator
  3. *
  4. * (c) Adrian Smith 2012-2015, triode1@btinternet.com
  5. * Ralph Irving 2015-2017, ralph_irving@hotmail.com
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. // Scale and pack functions
  22. #include "squeezelite.h"
  23. #if BYTES_PER_FRAM == 4
  24. #define MAX_VAL16 0x7fffffffLL
  25. #define MAX_SCALESAMPLE 0x7fffffffffffLL
  26. #define MIN_SCALESAMPLE -MAX_SCALESAMPLE
  27. #else
  28. #define MAX_SCALESAMPLE 0x7fffffffffffLL
  29. #define MIN_SCALESAMPLE -MAX_SCALESAMPLE
  30. #endif
  31. // inlining these on windows prevents them being linkable...
  32. #if !WIN
  33. inline
  34. #endif
  35. s32_t gain(s32_t gain, s32_t sample) {
  36. s64_t res = (s64_t)gain * (s64_t)sample;
  37. if (res > MAX_SCALESAMPLE) res = MAX_SCALESAMPLE;
  38. if (res < MIN_SCALESAMPLE) res = MIN_SCALESAMPLE;
  39. return (s32_t) (res >> 16);
  40. }
  41. #if !WIN
  42. inline
  43. #endif
  44. s32_t to_gain(float f) {
  45. return (s32_t)(f * 65536.0F);
  46. }
  47. void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format) {
  48. // in-place copy input samples if mono/combined is used (never happens with DSD active)
  49. if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) {
  50. s32_t *ptr = inputptr;
  51. frames_t count = cnt;
  52. gainL &= ~MONO_FLAG; gainR &= ~MONO_FLAG;
  53. while (count--) {
  54. // use 64 bits integer for purists but should really not care
  55. *ptr = *(ptr + 1) = ((s64_t) *ptr + (s64_t) *(ptr + 1)) / 2;
  56. ptr += 2;
  57. }
  58. } else if (gainL & MONO_FLAG) {
  59. s32_t *ptr = inputptr + 1;
  60. frames_t count = cnt;
  61. gainL &= ~MONO_FLAG;
  62. while (count--) {
  63. *(ptr - 1) = *ptr;
  64. ptr += 2;
  65. }
  66. } else if (gainR & MONO_FLAG) {
  67. s32_t *ptr = inputptr;
  68. frames_t count = cnt;
  69. gainR &= ~MONO_FLAG;
  70. while (count--) {
  71. *(ptr + 1) = *ptr;
  72. ptr += 2;
  73. }
  74. }
  75. switch(format) {
  76. #if DSD
  77. case U32_LE:
  78. {
  79. #if SL_LITTLE_ENDIAN
  80. memcpy(outputptr, inputptr, cnt * BYTES_PER_FRAME);
  81. #else
  82. u32_t *optr = (u32_t *)(void *)outputptr;
  83. while (cnt--) {
  84. s32_t lsample = *(inputptr++);
  85. s32_t rsample = *(inputptr++);
  86. *(optr++) =
  87. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  88. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  89. *(optr++) =
  90. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  91. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  92. }
  93. #endif
  94. }
  95. break;
  96. case U32_BE:
  97. {
  98. #if SL_LITTLE_ENDIAN
  99. u32_t *optr = (u32_t *)(void *)outputptr;
  100. while (cnt--) {
  101. s32_t lsample = *(inputptr++);
  102. s32_t rsample = *(inputptr++);
  103. *(optr++) =
  104. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  105. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  106. *(optr++) =
  107. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  108. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  109. }
  110. #else
  111. memcpy(outputptr, inputptr, cnt * BYTES_PER_FRAME);
  112. #endif
  113. }
  114. break;
  115. case U16_LE:
  116. {
  117. u32_t *optr = (u32_t *)(void *)outputptr;
  118. #if SL_LITTLE_ENDIAN
  119. while (cnt--) {
  120. *(optr++) = (*(inputptr) >> 16 & 0x0000ffff) | (*(inputptr + 1) & 0xffff0000);
  121. inputptr += 2;
  122. }
  123. #else
  124. while (cnt--) {
  125. s32_t lsample = *(inputptr++);
  126. s32_t rsample = *(inputptr++);
  127. *(optr++) =
  128. (lsample & 0x00ff0000) << 8 | (lsample & 0xff000000) >> 8 |
  129. (rsample & 0x00ff0000) >> 8 | (rsample & 0xff000000) >> 24;
  130. }
  131. #endif
  132. }
  133. break;
  134. case U16_BE:
  135. {
  136. u32_t *optr = (u32_t *)(void *)outputptr;
  137. #if SL_LITTLE_ENDIAN
  138. while (cnt--) {
  139. s32_t lsample = *(inputptr++);
  140. s32_t rsample = *(inputptr++);
  141. *(optr++) =
  142. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  143. (rsample & 0xff000000) >> 8 | (rsample & 0x00ff0000) << 8;
  144. }
  145. #else
  146. while (cnt--) {
  147. *(optr++) = (*(inputptr) & 0xffff0000) | (*(inputptr + 1) >> 16 & 0x0000ffff);
  148. inputptr += 2;
  149. }
  150. #endif
  151. }
  152. break;
  153. case U8:
  154. {
  155. u16_t *optr = (u16_t *)(void *)outputptr;
  156. #if SL_LITTLE_ENDIAN
  157. while (cnt--) {
  158. *(optr++) = (u16_t)((*(inputptr) >> 24 & 0x000000ff) | (*(inputptr + 1) >> 16 & 0x0000ff00));
  159. inputptr += 2;
  160. }
  161. #else
  162. while (cnt--) {
  163. *(optr++) = (u16_t)((*(inputptr) >> 16 & 0x0000ff00) | (*(inputptr + 1) >> 24 & 0x000000ff));
  164. inputptr += 2;
  165. }
  166. #endif
  167. }
  168. break;
  169. #endif
  170. case S16_LE:
  171. {
  172. u32_t *optr = (u32_t *)(void *)outputptr;
  173. #if SL_LITTLE_ENDIAN
  174. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  175. while (cnt--) {
  176. *(optr++) = (*(inputptr) >> 16 & 0x0000ffff) | (*(inputptr + 1) & 0xffff0000);
  177. inputptr += 2;
  178. }
  179. } else {
  180. while (cnt--) {
  181. *(optr++) = (gain(gainL, *(inputptr)) >> 16 & 0x0000ffff) | (gain(gainR, *(inputptr+1)) & 0xffff0000);
  182. inputptr += 2;
  183. }
  184. }
  185. #else
  186. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  187. while (cnt--) {
  188. s32_t lsample = *(inputptr++);
  189. s32_t rsample = *(inputptr++);
  190. *(optr++) =
  191. (lsample & 0x00ff0000) << 8 | (lsample & 0xff000000) >> 8 |
  192. (rsample & 0x00ff0000) >> 8 | (rsample & 0xff000000) >> 24;
  193. }
  194. } else {
  195. while (cnt--) {
  196. s32_t lsample = gain(gainL, *(inputptr++));
  197. s32_t rsample = gain(gainR, *(inputptr++));
  198. *(optr++) =
  199. (lsample & 0x00ff0000) << 8 | (lsample & 0xff000000) >> 8 |
  200. (rsample & 0x00ff0000) >> 8 | (rsample & 0xff000000) >> 24;
  201. }
  202. }
  203. #endif
  204. }
  205. break;
  206. case S24_LE:
  207. {
  208. u32_t *optr = (u32_t *)(void *)outputptr;
  209. #if SL_LITTLE_ENDIAN
  210. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  211. while (cnt--) {
  212. *(optr++) = *(inputptr++) >> 8;
  213. *(optr++) = *(inputptr++) >> 8;
  214. }
  215. } else {
  216. while (cnt--) {
  217. *(optr++) = gain(gainL, *(inputptr++)) >> 8;
  218. *(optr++) = gain(gainR, *(inputptr++)) >> 8;
  219. }
  220. }
  221. #else
  222. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  223. while (cnt--) {
  224. s32_t lsample = *(inputptr++);
  225. s32_t rsample = *(inputptr++);
  226. *(optr++) =
  227. (lsample & 0xff000000) >> 16 | (lsample & 0x00ff0000) | (lsample & 0x0000ff00 << 16);
  228. *(optr++) =
  229. (rsample & 0xff000000) >> 16 | (rsample & 0x00ff0000) | (rsample & 0x0000ff00 << 16);
  230. }
  231. } else {
  232. while (cnt--) {
  233. s32_t lsample = gain(gainL, *(inputptr++));
  234. s32_t rsample = gain(gainR, *(inputptr++));
  235. *(optr++) =
  236. (lsample & 0xff000000) >> 16 | (lsample & 0x00ff0000) | (lsample & 0x0000ff00 << 16);
  237. *(optr++) =
  238. (rsample & 0xff000000) >> 16 | (rsample & 0x00ff0000) | (rsample & 0x0000ff00 << 16);
  239. }
  240. }
  241. #endif
  242. }
  243. break;
  244. case S24_3LE:
  245. {
  246. u8_t *optr = (u8_t *)(void *)outputptr;
  247. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  248. while (cnt) {
  249. // attempt to do 32 bit memory accesses - move 2 frames at once: 16 bytes -> 12 bytes
  250. // falls through to exception case when not aligned or if less than 2 frames to move
  251. if (((uintptr_t)optr & 0x3) == 0 && cnt >= 2) {
  252. u32_t *o_ptr = (u32_t *)(void *)optr;
  253. while (cnt >= 2) {
  254. s32_t l1 = *(inputptr++); s32_t r1 = *(inputptr++);
  255. s32_t l2 = *(inputptr++); s32_t r2 = *(inputptr++);
  256. #if SL_LITTLE_ENDIAN
  257. *(o_ptr++) = (l1 & 0xffffff00) >> 8 | (r1 & 0x0000ff00) << 16;
  258. *(o_ptr++) = (r1 & 0xffff0000) >> 16 | (l2 & 0x00ffff00) << 8;
  259. *(o_ptr++) = (l2 & 0xff000000) >> 24 | (r2 & 0xffffff00);
  260. #else
  261. *(o_ptr++) = (l1 & 0x0000ff00) << 16 | (l1 & 0x00ff0000) | (l1 & 0xff000000) >> 16 |
  262. (r1 & 0x0000ff00) >> 8;
  263. *(o_ptr++) = (r1 & 0x00ff0000) << 8 | (r1 & 0xff000000) >> 8 | (l2 & 0x0000ff00) |
  264. (l2 & 0x00ff0000) >> 16;
  265. *(o_ptr++) = (l2 & 0xff000000) | (r2 & 0x0000ff00) << 8 | (r2 & 0x00ff0000) >> 8 |
  266. (r2 & 0xff000000) >> 24;
  267. #endif
  268. optr += 12;
  269. cnt -= 2;
  270. }
  271. } else {
  272. s32_t lsample = *(inputptr++);
  273. s32_t rsample = *(inputptr++);
  274. *(optr++) = (lsample & 0x0000ff00) >> 8;
  275. *(optr++) = (lsample & 0x00ff0000) >> 16;
  276. *(optr++) = (lsample & 0xff000000) >> 24;
  277. *(optr++) = (rsample & 0x0000ff00) >> 8;
  278. *(optr++) = (rsample & 0x00ff0000) >> 16;
  279. *(optr++) = (rsample & 0xff000000) >> 24;
  280. cnt--;
  281. }
  282. }
  283. } else {
  284. while (cnt) {
  285. // attempt to do 32 bit memory accesses - move 2 frames at once: 16 bytes -> 12 bytes
  286. // falls through to exception case when not aligned or if less than 2 frames to move
  287. if (((uintptr_t)optr & 0x3) == 0 && cnt >= 2) {
  288. u32_t *o_ptr = (u32_t *)(void *)optr;
  289. while (cnt >= 2) {
  290. s32_t l1 = gain(gainL, *(inputptr++)); s32_t r1 = gain(gainR, *(inputptr++));
  291. s32_t l2 = gain(gainL, *(inputptr++)); s32_t r2 = gain(gainR, *(inputptr++));
  292. #if SL_LITTLE_ENDIAN
  293. *(o_ptr++) = (l1 & 0xffffff00) >> 8 | (r1 & 0x0000ff00) << 16;
  294. *(o_ptr++) = (r1 & 0xffff0000) >> 16 | (l2 & 0x00ffff00) << 8;
  295. *(o_ptr++) = (l2 & 0xff000000) >> 24 | (r2 & 0xffffff00);
  296. #else
  297. *(o_ptr++) = (l1 & 0x0000ff00) << 16 | (l1 & 0x00ff0000) | (l1 & 0xff000000) >> 16 |
  298. (r1 & 0x0000ff00) >> 8;
  299. *(o_ptr++) = (r1 & 0x00ff0000) << 8 | (r1 & 0xff000000) >> 8 | (l2 & 0x0000ff00) |
  300. (l2 & 0x00ff0000) >> 16;
  301. *(o_ptr++) = (l2 & 0xff000000) | (r2 & 0x0000ff00) << 8 | (r2 & 0x00ff0000) >> 8 |
  302. (r2 & 0xff000000) >> 24;
  303. #endif
  304. optr += 12;
  305. cnt -= 2;
  306. }
  307. } else {
  308. s32_t lsample = gain(gainL, *(inputptr++));
  309. s32_t rsample = gain(gainR, *(inputptr++));
  310. *(optr++) = (lsample & 0x0000ff00) >> 8;
  311. *(optr++) = (lsample & 0x00ff0000) >> 16;
  312. *(optr++) = (lsample & 0xff000000) >> 24;
  313. *(optr++) = (rsample & 0x0000ff00) >> 8;
  314. *(optr++) = (rsample & 0x00ff0000) >> 16;
  315. *(optr++) = (rsample & 0xff000000) >> 24;
  316. cnt--;
  317. }
  318. }
  319. }
  320. }
  321. break;
  322. case S32_LE:
  323. {
  324. u32_t *optr = (u32_t *)(void *)outputptr;
  325. #if SL_LITTLE_ENDIAN
  326. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  327. memcpy(outputptr, inputptr, cnt * BYTES_PER_FRAME);
  328. } else {
  329. while (cnt--) {
  330. *(optr++) = gain(gainL, *(inputptr++));
  331. *(optr++) = gain(gainR, *(inputptr++));
  332. }
  333. }
  334. #else
  335. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  336. while (cnt--) {
  337. s32_t lsample = *(inputptr++);
  338. s32_t rsample = *(inputptr++);
  339. *(optr++) =
  340. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  341. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  342. *(optr++) =
  343. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  344. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  345. }
  346. } else {
  347. while (cnt--) {
  348. s32_t lsample = gain(gainL, *(inputptr++));
  349. s32_t rsample = gain(gainR, *(inputptr++));
  350. *(optr++) =
  351. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  352. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  353. *(optr++) =
  354. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  355. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  356. }
  357. }
  358. #endif
  359. }
  360. break;
  361. default:
  362. break;
  363. }
  364. }
  365. #if !WIN
  366. inline
  367. #endif
  368. void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  369. ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
  370. frames_t count = out_frames * 2;
  371. while (count--) {
  372. if (*cross_ptr > (ISAMPLE_T *)outputbuf->wrap) {
  373. *cross_ptr -= outputbuf->size / BYTES_PER_FRAME * 2;
  374. }
  375. *ptr = gain(cross_gain_out, *ptr) + gain(cross_gain_in, **cross_ptr);
  376. ptr++; (*cross_ptr)++;
  377. }
  378. }
  379. #if !WIN
  380. inline
  381. #endif
  382. void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) {
  383. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  384. return;
  385. } if ((gainR & MONO_FLAG) && (gainL & MONO_FLAG)) {
  386. ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
  387. ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
  388. gainL &= ~MONO_FLAG; gainR &= ~MONO_FLAG;
  389. while (count--) {
  390. *ptrL = *ptrR = (gain(gainL, *ptrL) + gain(gainR, *ptrR)) / 2;
  391. ptrL += 2; ptrR += 2;
  392. }
  393. } else if (gainL & MONO_FLAG) {
  394. ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
  395. while (count--) {
  396. *(ptr - 1) = *ptr = gain(gainR, *ptr);
  397. ptr += 2;
  398. }
  399. } else if (gainR & MONO_FLAG) {
  400. ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
  401. while (count--) {
  402. *(ptr + 1) = *ptr = gain(gainL, *ptr);
  403. ptr += 2;
  404. }
  405. } else {
  406. ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
  407. ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
  408. while (count--) {
  409. *ptrL = gain(gainL, *ptrL);
  410. *ptrR = gain(gainR, *ptrR);
  411. ptrL += 2; ptrR += 2;
  412. }
  413. }
  414. }