output_pack.c 11 KB

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