output_pack.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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. switch(format) {
  49. #if DSD
  50. case U32_LE:
  51. {
  52. #if SL_LITTLE_ENDIAN
  53. memcpy(outputptr, inputptr, cnt * BYTES_PER_FRAME);
  54. #else
  55. u32_t *optr = (u32_t *)(void *)outputptr;
  56. while (cnt--) {
  57. s32_t lsample = *(inputptr++);
  58. s32_t rsample = *(inputptr++);
  59. *(optr++) =
  60. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  61. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  62. *(optr++) =
  63. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  64. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  65. }
  66. #endif
  67. }
  68. break;
  69. case U32_BE:
  70. {
  71. #if SL_LITTLE_ENDIAN
  72. u32_t *optr = (u32_t *)(void *)outputptr;
  73. while (cnt--) {
  74. s32_t lsample = *(inputptr++);
  75. s32_t rsample = *(inputptr++);
  76. *(optr++) =
  77. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  78. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  79. *(optr++) =
  80. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  81. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  82. }
  83. #else
  84. memcpy(outputptr, inputptr, cnt * BYTES_PER_FRAME);
  85. #endif
  86. }
  87. break;
  88. case U16_LE:
  89. {
  90. u32_t *optr = (u32_t *)(void *)outputptr;
  91. #if SL_LITTLE_ENDIAN
  92. while (cnt--) {
  93. *(optr++) = (*(inputptr) >> 16 & 0x0000ffff) | (*(inputptr + 1) & 0xffff0000);
  94. inputptr += 2;
  95. }
  96. #else
  97. while (cnt--) {
  98. s32_t lsample = *(inputptr++);
  99. s32_t rsample = *(inputptr++);
  100. *(optr++) =
  101. (lsample & 0x00ff0000) << 8 | (lsample & 0xff000000) >> 8 |
  102. (rsample & 0x00ff0000) >> 8 | (rsample & 0xff000000) >> 24;
  103. }
  104. #endif
  105. }
  106. break;
  107. case U16_BE:
  108. {
  109. u32_t *optr = (u32_t *)(void *)outputptr;
  110. #if SL_LITTLE_ENDIAN
  111. while (cnt--) {
  112. s32_t lsample = *(inputptr++);
  113. s32_t rsample = *(inputptr++);
  114. *(optr++) =
  115. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  116. (rsample & 0xff000000) >> 8 | (rsample & 0x00ff0000) << 8;
  117. }
  118. #else
  119. while (cnt--) {
  120. *(optr++) = (*(inputptr) & 0xffff0000) | (*(inputptr + 1) >> 16 & 0x0000ffff);
  121. inputptr += 2;
  122. }
  123. #endif
  124. }
  125. break;
  126. case U8:
  127. {
  128. u16_t *optr = (u16_t *)(void *)outputptr;
  129. #if SL_LITTLE_ENDIAN
  130. while (cnt--) {
  131. *(optr++) = (u16_t)((*(inputptr) >> 24 & 0x000000ff) | (*(inputptr + 1) >> 16 & 0x0000ff00));
  132. inputptr += 2;
  133. }
  134. #else
  135. while (cnt--) {
  136. *(optr++) = (u16_t)((*(inputptr) >> 16 & 0x0000ff00) | (*(inputptr + 1) >> 24 & 0x000000ff));
  137. inputptr += 2;
  138. }
  139. #endif
  140. }
  141. break;
  142. #endif
  143. case S16_LE:
  144. {
  145. u32_t *optr = (u32_t *)(void *)outputptr;
  146. #if SL_LITTLE_ENDIAN
  147. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  148. while (cnt--) {
  149. *(optr++) = (*(inputptr) >> 16 & 0x0000ffff) | (*(inputptr + 1) & 0xffff0000);
  150. inputptr += 2;
  151. }
  152. } else {
  153. while (cnt--) {
  154. *(optr++) = (gain(gainL, *(inputptr)) >> 16 & 0x0000ffff) | (gain(gainR, *(inputptr+1)) & 0xffff0000);
  155. inputptr += 2;
  156. }
  157. }
  158. #else
  159. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  160. while (cnt--) {
  161. s32_t lsample = *(inputptr++);
  162. s32_t rsample = *(inputptr++);
  163. *(optr++) =
  164. (lsample & 0x00ff0000) << 8 | (lsample & 0xff000000) >> 8 |
  165. (rsample & 0x00ff0000) >> 8 | (rsample & 0xff000000) >> 24;
  166. }
  167. } else {
  168. while (cnt--) {
  169. s32_t lsample = gain(gainL, *(inputptr++));
  170. s32_t rsample = gain(gainR, *(inputptr++));
  171. *(optr++) =
  172. (lsample & 0x00ff0000) << 8 | (lsample & 0xff000000) >> 8 |
  173. (rsample & 0x00ff0000) >> 8 | (rsample & 0xff000000) >> 24;
  174. }
  175. }
  176. #endif
  177. }
  178. break;
  179. case S24_LE:
  180. {
  181. u32_t *optr = (u32_t *)(void *)outputptr;
  182. #if SL_LITTLE_ENDIAN
  183. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  184. while (cnt--) {
  185. *(optr++) = *(inputptr++) >> 8;
  186. *(optr++) = *(inputptr++) >> 8;
  187. }
  188. } else {
  189. while (cnt--) {
  190. *(optr++) = gain(gainL, *(inputptr++)) >> 8;
  191. *(optr++) = gain(gainR, *(inputptr++)) >> 8;
  192. }
  193. }
  194. #else
  195. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  196. while (cnt--) {
  197. s32_t lsample = *(inputptr++);
  198. s32_t rsample = *(inputptr++);
  199. *(optr++) =
  200. (lsample & 0xff000000) >> 16 | (lsample & 0x00ff0000) | (lsample & 0x0000ff00 << 16);
  201. *(optr++) =
  202. (rsample & 0xff000000) >> 16 | (rsample & 0x00ff0000) | (rsample & 0x0000ff00 << 16);
  203. }
  204. } else {
  205. while (cnt--) {
  206. s32_t lsample = gain(gainL, *(inputptr++));
  207. s32_t rsample = gain(gainR, *(inputptr++));
  208. *(optr++) =
  209. (lsample & 0xff000000) >> 16 | (lsample & 0x00ff0000) | (lsample & 0x0000ff00 << 16);
  210. *(optr++) =
  211. (rsample & 0xff000000) >> 16 | (rsample & 0x00ff0000) | (rsample & 0x0000ff00 << 16);
  212. }
  213. }
  214. #endif
  215. }
  216. break;
  217. case S24_3LE:
  218. {
  219. u8_t *optr = (u8_t *)(void *)outputptr;
  220. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  221. while (cnt) {
  222. // attempt to do 32 bit memory accesses - move 2 frames at once: 16 bytes -> 12 bytes
  223. // falls through to exception case when not aligned or if less than 2 frames to move
  224. if (((uintptr_t)optr & 0x3) == 0 && cnt >= 2) {
  225. u32_t *o_ptr = (u32_t *)(void *)optr;
  226. while (cnt >= 2) {
  227. s32_t l1 = *(inputptr++); s32_t r1 = *(inputptr++);
  228. s32_t l2 = *(inputptr++); s32_t r2 = *(inputptr++);
  229. #if SL_LITTLE_ENDIAN
  230. *(o_ptr++) = (l1 & 0xffffff00) >> 8 | (r1 & 0x0000ff00) << 16;
  231. *(o_ptr++) = (r1 & 0xffff0000) >> 16 | (l2 & 0x00ffff00) << 8;
  232. *(o_ptr++) = (l2 & 0xff000000) >> 24 | (r2 & 0xffffff00);
  233. #else
  234. *(o_ptr++) = (l1 & 0x0000ff00) << 16 | (l1 & 0x00ff0000) | (l1 & 0xff000000) >> 16 |
  235. (r1 & 0x0000ff00) >> 8;
  236. *(o_ptr++) = (r1 & 0x00ff0000) << 8 | (r1 & 0xff000000) >> 8 | (l2 & 0x0000ff00) |
  237. (l2 & 0x00ff0000) >> 16;
  238. *(o_ptr++) = (l2 & 0xff000000) | (r2 & 0x0000ff00) << 8 | (r2 & 0x00ff0000) >> 8 |
  239. (r2 & 0xff000000) >> 24;
  240. #endif
  241. optr += 12;
  242. cnt -= 2;
  243. }
  244. } else {
  245. s32_t lsample = *(inputptr++);
  246. s32_t rsample = *(inputptr++);
  247. *(optr++) = (lsample & 0x0000ff00) >> 8;
  248. *(optr++) = (lsample & 0x00ff0000) >> 16;
  249. *(optr++) = (lsample & 0xff000000) >> 24;
  250. *(optr++) = (rsample & 0x0000ff00) >> 8;
  251. *(optr++) = (rsample & 0x00ff0000) >> 16;
  252. *(optr++) = (rsample & 0xff000000) >> 24;
  253. cnt--;
  254. }
  255. }
  256. } else {
  257. while (cnt) {
  258. // attempt to do 32 bit memory accesses - move 2 frames at once: 16 bytes -> 12 bytes
  259. // falls through to exception case when not aligned or if less than 2 frames to move
  260. if (((uintptr_t)optr & 0x3) == 0 && cnt >= 2) {
  261. u32_t *o_ptr = (u32_t *)(void *)optr;
  262. while (cnt >= 2) {
  263. s32_t l1 = gain(gainL, *(inputptr++)); s32_t r1 = gain(gainR, *(inputptr++));
  264. s32_t l2 = gain(gainL, *(inputptr++)); s32_t r2 = gain(gainR, *(inputptr++));
  265. #if SL_LITTLE_ENDIAN
  266. *(o_ptr++) = (l1 & 0xffffff00) >> 8 | (r1 & 0x0000ff00) << 16;
  267. *(o_ptr++) = (r1 & 0xffff0000) >> 16 | (l2 & 0x00ffff00) << 8;
  268. *(o_ptr++) = (l2 & 0xff000000) >> 24 | (r2 & 0xffffff00);
  269. #else
  270. *(o_ptr++) = (l1 & 0x0000ff00) << 16 | (l1 & 0x00ff0000) | (l1 & 0xff000000) >> 16 |
  271. (r1 & 0x0000ff00) >> 8;
  272. *(o_ptr++) = (r1 & 0x00ff0000) << 8 | (r1 & 0xff000000) >> 8 | (l2 & 0x0000ff00) |
  273. (l2 & 0x00ff0000) >> 16;
  274. *(o_ptr++) = (l2 & 0xff000000) | (r2 & 0x0000ff00) << 8 | (r2 & 0x00ff0000) >> 8 |
  275. (r2 & 0xff000000) >> 24;
  276. #endif
  277. optr += 12;
  278. cnt -= 2;
  279. }
  280. } else {
  281. s32_t lsample = gain(gainL, *(inputptr++));
  282. s32_t rsample = gain(gainR, *(inputptr++));
  283. *(optr++) = (lsample & 0x0000ff00) >> 8;
  284. *(optr++) = (lsample & 0x00ff0000) >> 16;
  285. *(optr++) = (lsample & 0xff000000) >> 24;
  286. *(optr++) = (rsample & 0x0000ff00) >> 8;
  287. *(optr++) = (rsample & 0x00ff0000) >> 16;
  288. *(optr++) = (rsample & 0xff000000) >> 24;
  289. cnt--;
  290. }
  291. }
  292. }
  293. }
  294. break;
  295. case S32_LE:
  296. {
  297. u32_t *optr = (u32_t *)(void *)outputptr;
  298. #if SL_LITTLE_ENDIAN
  299. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  300. memcpy(outputptr, inputptr, cnt * BYTES_PER_FRAME);
  301. } else {
  302. while (cnt--) {
  303. *(optr++) = gain(gainL, *(inputptr++));
  304. *(optr++) = gain(gainR, *(inputptr++));
  305. }
  306. }
  307. #else
  308. if (gainL == FIXED_ONE && gainR == FIXED_ONE) {
  309. while (cnt--) {
  310. s32_t lsample = *(inputptr++);
  311. s32_t rsample = *(inputptr++);
  312. *(optr++) =
  313. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  314. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  315. *(optr++) =
  316. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  317. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  318. }
  319. } else {
  320. while (cnt--) {
  321. s32_t lsample = gain(gainL, *(inputptr++));
  322. s32_t rsample = gain(gainR, *(inputptr++));
  323. *(optr++) =
  324. (lsample & 0xff000000) >> 24 | (lsample & 0x00ff0000) >> 8 |
  325. (lsample & 0x0000ff00) << 8 | (lsample & 0x000000ff) << 24;
  326. *(optr++) =
  327. (rsample & 0xff000000) >> 24 | (rsample & 0x00ff0000) >> 8 |
  328. (rsample & 0x0000ff00) << 8 | (rsample & 0x000000ff) << 24;
  329. }
  330. }
  331. #endif
  332. }
  333. break;
  334. default:
  335. break;
  336. }
  337. }
  338. #if !WIN
  339. inline
  340. #endif
  341. void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
  342. ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
  343. frames_t count = out_frames * 2;
  344. while (count--) {
  345. if (*cross_ptr > (ISAMPLE_T *)outputbuf->wrap) {
  346. *cross_ptr -= outputbuf->size / BYTES_PER_FRAME * 2;
  347. }
  348. *ptr = gain(cross_gain_out, *ptr) + gain(cross_gain_in, **cross_ptr);
  349. ptr++; (*cross_ptr)++;
  350. }
  351. }
  352. #if !WIN
  353. inline
  354. #endif
  355. void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) {
  356. ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
  357. ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
  358. while (count--) {
  359. *ptrL = gain(gainL, *ptrL);
  360. *ptrR = gain(gainR, *ptrR);
  361. ptrL += 2;
  362. ptrR += 2;
  363. }
  364. }