/project/jni/sdl_mixer/effect_position.c

https://github.com/aichunyu/FFPlayer · C · 1617 lines · 1333 code · 140 blank · 144 comment · 233 complexity · 87120104d1d50c0c647ea1787836bc04 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. SDL_mixer: An audio mixer library based on the SDL library
  3. Copyright (C) 1997-2009 Sam Lantinga
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. This file by Ryan C. Gordon (icculus@icculus.org)
  16. These are some internally supported special effects that use SDL_mixer's
  17. effect callback API. They are meant for speed over quality. :)
  18. */
  19. /* $Id: effect_position.c 5045 2009-10-11 02:59:12Z icculus $ */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "SDL.h"
  24. #include "SDL_mixer.h"
  25. #include "SDL_endian.h"
  26. #define __MIX_INTERNAL_EFFECT__
  27. #include "effects_internal.h"
  28. /* profile code:
  29. #include <sys/time.h>
  30. #include <unistd.h>
  31. struct timeval tv1;
  32. struct timeval tv2;
  33. gettimeofday(&tv1, NULL);
  34. ... do your thing here ...
  35. gettimeofday(&tv2, NULL);
  36. printf("%ld\n", tv2.tv_usec - tv1.tv_usec);
  37. */
  38. /*
  39. * Positional effects...panning, distance attenuation, etc.
  40. */
  41. typedef struct _Eff_positionargs
  42. {
  43. volatile float left_f;
  44. volatile float right_f;
  45. volatile Uint8 left_u8;
  46. volatile Uint8 right_u8;
  47. volatile float left_rear_f;
  48. volatile float right_rear_f;
  49. volatile float center_f;
  50. volatile float lfe_f;
  51. volatile Uint8 left_rear_u8;
  52. volatile Uint8 right_rear_u8;
  53. volatile Uint8 center_u8;
  54. volatile Uint8 lfe_u8;
  55. volatile float distance_f;
  56. volatile Uint8 distance_u8;
  57. volatile Sint16 room_angle;
  58. volatile int in_use;
  59. volatile int channels;
  60. } position_args;
  61. static position_args **pos_args_array = NULL;
  62. static position_args *pos_args_global = NULL;
  63. static int position_channels = 0;
  64. void _Eff_PositionDeinit(void)
  65. {
  66. int i;
  67. for (i = 0; i < position_channels; i++) {
  68. free(pos_args_array[i]);
  69. }
  70. position_channels = 0;
  71. free(pos_args_global);
  72. pos_args_global = NULL;
  73. free(pos_args_array);
  74. pos_args_array = NULL;
  75. }
  76. /* This just frees up the callback-specific data. */
  77. static void _Eff_PositionDone(int channel, void *udata)
  78. {
  79. if (channel < 0) {
  80. if (pos_args_global != NULL) {
  81. free(pos_args_global);
  82. pos_args_global = NULL;
  83. }
  84. }
  85. else if (pos_args_array[channel] != NULL) {
  86. free(pos_args_array[channel]);
  87. pos_args_array[channel] = NULL;
  88. }
  89. }
  90. static void _Eff_position_u8(int chan, void *stream, int len, void *udata)
  91. {
  92. volatile position_args *args = (volatile position_args *) udata;
  93. Uint8 *ptr = (Uint8 *) stream;
  94. int i;
  95. /*
  96. * if there's only a mono channnel (the only way we wouldn't have
  97. * a len divisible by 2 here), then left_f and right_f are always
  98. * 1.0, and are therefore throwaways.
  99. */
  100. if (len % sizeof (Uint16) != 0) {
  101. *ptr = (Uint8) (((float) *ptr) * args->distance_f);
  102. ptr++;
  103. len--;
  104. }
  105. if (args->room_angle == 180)
  106. for (i = 0; i < len; i += sizeof (Uint8) * 2) {
  107. /* must adjust the sample so that 0 is the center */
  108. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  109. * args->right_f) * args->distance_f) + 128);
  110. ptr++;
  111. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  112. * args->left_f) * args->distance_f) + 128);
  113. ptr++;
  114. }
  115. else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
  116. /* must adjust the sample so that 0 is the center */
  117. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  118. * args->left_f) * args->distance_f) + 128);
  119. ptr++;
  120. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  121. * args->right_f) * args->distance_f) + 128);
  122. ptr++;
  123. }
  124. }
  125. static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
  126. {
  127. volatile position_args *args = (volatile position_args *) udata;
  128. Uint8 *ptr = (Uint8 *) stream;
  129. int i;
  130. /*
  131. * if there's only a mono channnel (the only way we wouldn't have
  132. * a len divisible by 2 here), then left_f and right_f are always
  133. * 1.0, and are therefore throwaways.
  134. */
  135. if (len % sizeof (Uint16) != 0) {
  136. *ptr = (Uint8) (((float) *ptr) * args->distance_f);
  137. ptr++;
  138. len--;
  139. }
  140. if (args->room_angle == 0)
  141. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  142. /* must adjust the sample so that 0 is the center */
  143. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  144. * args->left_f) * args->distance_f) + 128);
  145. ptr++;
  146. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  147. * args->right_f) * args->distance_f) + 128);
  148. ptr++;
  149. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  150. * args->left_rear_f) * args->distance_f) + 128);
  151. ptr++;
  152. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  153. * args->right_rear_f) * args->distance_f) + 128);
  154. ptr++;
  155. }
  156. else if (args->room_angle == 90)
  157. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  158. /* must adjust the sample so that 0 is the center */
  159. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  160. * args->right_f) * args->distance_f) + 128);
  161. ptr++;
  162. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  163. * args->right_rear_f) * args->distance_f) + 128);
  164. ptr++;
  165. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  166. * args->left_f) * args->distance_f) + 128);
  167. ptr++;
  168. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  169. * args->left_rear_f) * args->distance_f) + 128);
  170. ptr++;
  171. }
  172. else if (args->room_angle == 180)
  173. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  174. /* must adjust the sample so that 0 is the center */
  175. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  176. * args->right_rear_f) * args->distance_f) + 128);
  177. ptr++;
  178. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  179. * args->left_rear_f) * args->distance_f) + 128);
  180. ptr++;
  181. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  182. * args->right_f) * args->distance_f) + 128);
  183. ptr++;
  184. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  185. * args->left_f) * args->distance_f) + 128);
  186. ptr++;
  187. }
  188. else if (args->room_angle == 270)
  189. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  190. /* must adjust the sample so that 0 is the center */
  191. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  192. * args->left_rear_f) * args->distance_f) + 128);
  193. ptr++;
  194. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  195. * args->left_f) * args->distance_f) + 128);
  196. ptr++;
  197. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  198. * args->right_rear_f) * args->distance_f) + 128);
  199. ptr++;
  200. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  201. * args->right_f) * args->distance_f) + 128);
  202. ptr++;
  203. }
  204. }
  205. static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
  206. {
  207. volatile position_args *args = (volatile position_args *) udata;
  208. Uint8 *ptr = (Uint8 *) stream;
  209. int i;
  210. /*
  211. * if there's only a mono channnel (the only way we wouldn't have
  212. * a len divisible by 2 here), then left_f and right_f are always
  213. * 1.0, and are therefore throwaways.
  214. */
  215. if (len % sizeof (Uint16) != 0) {
  216. *ptr = (Uint8) (((float) *ptr) * args->distance_f);
  217. ptr++;
  218. len--;
  219. }
  220. if (args->room_angle == 0)
  221. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  222. /* must adjust the sample so that 0 is the center */
  223. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  224. * args->left_f) * args->distance_f) + 128);
  225. ptr++;
  226. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  227. * args->right_f) * args->distance_f) + 128);
  228. ptr++;
  229. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  230. * args->left_rear_f) * args->distance_f) + 128);
  231. ptr++;
  232. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  233. * args->right_rear_f) * args->distance_f) + 128);
  234. ptr++;
  235. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  236. * args->center_f) * args->distance_f) + 128);
  237. ptr++;
  238. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  239. * args->lfe_f) * args->distance_f) + 128);
  240. ptr++;
  241. }
  242. else if (args->room_angle == 90)
  243. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  244. /* must adjust the sample so that 0 is the center */
  245. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  246. * args->right_f) * args->distance_f) + 128);
  247. ptr++;
  248. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  249. * args->right_rear_f) * args->distance_f) + 128);
  250. ptr++;
  251. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  252. * args->left_f) * args->distance_f) + 128);
  253. ptr++;
  254. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  255. * args->left_rear_f) * args->distance_f) + 128);
  256. ptr++;
  257. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  258. * args->right_rear_f) * args->distance_f/2) + 128)
  259. + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  260. * args->right_f) * args->distance_f/2) + 128);
  261. ptr++;
  262. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  263. * args->lfe_f) * args->distance_f) + 128);
  264. ptr++;
  265. }
  266. else if (args->room_angle == 180)
  267. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  268. /* must adjust the sample so that 0 is the center */
  269. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  270. * args->right_rear_f) * args->distance_f) + 128);
  271. ptr++;
  272. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  273. * args->left_rear_f) * args->distance_f) + 128);
  274. ptr++;
  275. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  276. * args->right_f) * args->distance_f) + 128);
  277. ptr++;
  278. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  279. * args->left_f) * args->distance_f) + 128);
  280. ptr++;
  281. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  282. * args->right_rear_f) * args->distance_f/2) + 128)
  283. + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  284. * args->left_rear_f) * args->distance_f/2) + 128);
  285. ptr++;
  286. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  287. * args->lfe_f) * args->distance_f) + 128);
  288. ptr++;
  289. }
  290. else if (args->room_angle == 270)
  291. for (i = 0; i < len; i += sizeof (Uint8) * 6) {
  292. /* must adjust the sample so that 0 is the center */
  293. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  294. * args->left_rear_f) * args->distance_f) + 128);
  295. ptr++;
  296. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  297. * args->left_f) * args->distance_f) + 128);
  298. ptr++;
  299. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  300. * args->right_rear_f) * args->distance_f) + 128);
  301. ptr++;
  302. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  303. * args->right_f) * args->distance_f) + 128);
  304. ptr++;
  305. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  306. * args->left_f) * args->distance_f/2) + 128)
  307. + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  308. * args->left_rear_f) * args->distance_f/2) + 128);
  309. ptr++;
  310. *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
  311. * args->lfe_f) * args->distance_f) + 128);
  312. ptr++;
  313. }
  314. }
  315. /*
  316. * This one runs about 10.1 times faster than the non-table version, with
  317. * no loss in quality. It does, however, require 64k of memory for the
  318. * lookup table. Also, this will only update position information once per
  319. * call; the non-table version always checks the arguments for each sample,
  320. * in case the user has called Mix_SetPanning() or whatnot again while this
  321. * callback is running.
  322. */
  323. static void _Eff_position_table_u8(int chan, void *stream, int len, void *udata)
  324. {
  325. volatile position_args *args = (volatile position_args *) udata;
  326. Uint8 *ptr = (Uint8 *) stream;
  327. Uint32 *p;
  328. int i;
  329. Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8);
  330. Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
  331. Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
  332. if (args->room_angle == 180) {
  333. Uint8 *temp = l;
  334. l = r;
  335. r = temp;
  336. }
  337. /*
  338. * if there's only a mono channnel, then l[] and r[] are always
  339. * volume 255, and are therefore throwaways. Still, we have to
  340. * be sure not to overrun the audio buffer...
  341. */
  342. while (len % sizeof (Uint32) != 0) {
  343. *ptr = d[l[*ptr]];
  344. ptr++;
  345. if (args->channels > 1) {
  346. *ptr = d[r[*ptr]];
  347. ptr++;
  348. }
  349. len -= args->channels;
  350. }
  351. p = (Uint32 *) ptr;
  352. for (i = 0; i < len; i += sizeof (Uint32)) {
  353. #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
  354. *p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
  355. (d[r[(*p & 0x00FF0000) >> 16]] << 16) |
  356. (d[l[(*p & 0x0000FF00) >> 8]] << 8) |
  357. (d[r[(*p & 0x000000FF) ]] ) ;
  358. #else
  359. *p = (d[r[(*p & 0xFF000000) >> 24]] << 24) |
  360. (d[l[(*p & 0x00FF0000) >> 16]] << 16) |
  361. (d[r[(*p & 0x0000FF00) >> 8]] << 8) |
  362. (d[l[(*p & 0x000000FF) ]] ) ;
  363. #endif
  364. ++p;
  365. }
  366. }
  367. static void _Eff_position_s8(int chan, void *stream, int len, void *udata)
  368. {
  369. volatile position_args *args = (volatile position_args *) udata;
  370. Sint8 *ptr = (Sint8 *) stream;
  371. int i;
  372. /*
  373. * if there's only a mono channnel (the only way we wouldn't have
  374. * a len divisible by 2 here), then left_f and right_f are always
  375. * 1.0, and are therefore throwaways.
  376. */
  377. if (len % sizeof (Sint16) != 0) {
  378. *ptr = (Sint8) (((float) *ptr) * args->distance_f);
  379. ptr++;
  380. len--;
  381. }
  382. if (args->room_angle == 180)
  383. for (i = 0; i < len; i += sizeof (Sint8) * 2) {
  384. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
  385. ptr++;
  386. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
  387. ptr++;
  388. }
  389. else
  390. for (i = 0; i < len; i += sizeof (Sint8) * 2) {
  391. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
  392. ptr++;
  393. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
  394. ptr++;
  395. }
  396. }
  397. static void _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
  398. {
  399. volatile position_args *args = (volatile position_args *) udata;
  400. Sint8 *ptr = (Sint8 *) stream;
  401. int i;
  402. /*
  403. * if there's only a mono channnel (the only way we wouldn't have
  404. * a len divisible by 2 here), then left_f and right_f are always
  405. * 1.0, and are therefore throwaways.
  406. */
  407. if (len % sizeof (Sint16) != 0) {
  408. *ptr = (Sint8) (((float) *ptr) * args->distance_f);
  409. ptr++;
  410. len--;
  411. }
  412. for (i = 0; i < len; i += sizeof (Sint8) * 4) {
  413. switch (args->room_angle) {
  414. case 0:
  415. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  416. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  417. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  418. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  419. break;
  420. case 90:
  421. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  422. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  423. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  424. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  425. break;
  426. case 180:
  427. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  428. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  429. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  430. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  431. break;
  432. case 270:
  433. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  434. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  435. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  436. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  437. break;
  438. }
  439. }
  440. }
  441. static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
  442. {
  443. volatile position_args *args = (volatile position_args *) udata;
  444. Sint8 *ptr = (Sint8 *) stream;
  445. int i;
  446. /*
  447. * if there's only a mono channnel (the only way we wouldn't have
  448. * a len divisible by 2 here), then left_f and right_f are always
  449. * 1.0, and are therefore throwaways.
  450. */
  451. if (len % sizeof (Sint16) != 0) {
  452. *ptr = (Sint8) (((float) *ptr) * args->distance_f);
  453. ptr++;
  454. len--;
  455. }
  456. for (i = 0; i < len; i += sizeof (Sint8) * 6) {
  457. switch (args->room_angle) {
  458. case 0:
  459. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  460. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  461. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  462. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  463. *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
  464. *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
  465. break;
  466. case 90:
  467. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  468. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  469. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  470. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  471. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
  472. + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
  473. *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
  474. break;
  475. case 180:
  476. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  477. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  478. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  479. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  480. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
  481. + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
  482. *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
  483. break;
  484. case 270:
  485. *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
  486. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
  487. *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
  488. *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
  489. *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
  490. + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
  491. *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
  492. break;
  493. }
  494. }
  495. }
  496. /*
  497. * This one runs about 10.1 times faster than the non-table version, with
  498. * no loss in quality. It does, however, require 64k of memory for the
  499. * lookup table. Also, this will only update position information once per
  500. * call; the non-table version always checks the arguments for each sample,
  501. * in case the user has called Mix_SetPanning() or whatnot again while this
  502. * callback is running.
  503. */
  504. static void _Eff_position_table_s8(int chan, void *stream, int len, void *udata)
  505. {
  506. volatile position_args *args = (volatile position_args *) udata;
  507. Sint8 *ptr = (Sint8 *) stream;
  508. Uint32 *p;
  509. int i;
  510. Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8);
  511. Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
  512. Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
  513. if (args->room_angle == 180) {
  514. Sint8 *temp = l;
  515. l = r;
  516. r = temp;
  517. }
  518. while (len % sizeof (Uint32) != 0) {
  519. *ptr = d[l[*ptr]];
  520. ptr++;
  521. if (args->channels > 1) {
  522. *ptr = d[r[*ptr]];
  523. ptr++;
  524. }
  525. len -= args->channels;
  526. }
  527. p = (Uint32 *) ptr;
  528. for (i = 0; i < len; i += sizeof (Uint32)) {
  529. #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
  530. *p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
  531. (d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
  532. (d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
  533. (d[r[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
  534. #else
  535. *p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
  536. (d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
  537. (d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
  538. (d[l[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
  539. #endif
  540. ++p;
  541. }
  542. }
  543. /* !!! FIXME : Optimize the code for 16-bit samples? */
  544. static void _Eff_position_u16lsb(int chan, void *stream, int len, void *udata)
  545. {
  546. volatile position_args *args = (volatile position_args *) udata;
  547. Uint16 *ptr = (Uint16 *) stream;
  548. int i;
  549. for (i = 0; i < len; i += sizeof (Uint16) * 2) {
  550. Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
  551. Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
  552. Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
  553. * args->distance_f) + 32768);
  554. Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
  555. * args->distance_f) + 32768);
  556. if (args->room_angle == 180) {
  557. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  558. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  559. }
  560. else {
  561. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  562. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  563. }
  564. }
  565. }
  566. static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
  567. {
  568. volatile position_args *args = (volatile position_args *) udata;
  569. Uint16 *ptr = (Uint16 *) stream;
  570. int i;
  571. for (i = 0; i < len; i += sizeof (Uint16) * 4) {
  572. Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
  573. Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
  574. Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
  575. Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
  576. Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
  577. * args->distance_f) + 32768);
  578. Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
  579. * args->distance_f) + 32768);
  580. Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
  581. * args->distance_f) + 32768);
  582. Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
  583. * args->distance_f) + 32768);
  584. switch (args->room_angle) {
  585. case 0:
  586. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  587. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  588. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  589. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  590. break;
  591. case 90:
  592. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  593. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  594. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  595. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  596. break;
  597. case 180:
  598. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  599. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  600. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  601. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  602. break;
  603. case 270:
  604. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  605. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  606. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  607. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  608. break;
  609. }
  610. }
  611. }
  612. static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
  613. {
  614. volatile position_args *args = (volatile position_args *) udata;
  615. Uint16 *ptr = (Uint16 *) stream;
  616. int i;
  617. for (i = 0; i < len; i += sizeof (Uint16) * 6) {
  618. Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
  619. Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
  620. Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
  621. Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
  622. Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
  623. Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
  624. Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
  625. * args->distance_f) + 32768);
  626. Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
  627. * args->distance_f) + 32768);
  628. Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
  629. * args->distance_f) + 32768);
  630. Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
  631. * args->distance_f) + 32768);
  632. Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
  633. * args->distance_f) + 32768);
  634. Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
  635. * args->distance_f) + 32768);
  636. switch (args->room_angle) {
  637. case 0:
  638. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  639. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  640. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  641. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  642. *(ptr++) = (Uint16) SDL_SwapLE16(swapce);
  643. *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
  644. break;
  645. case 90:
  646. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  647. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  648. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  649. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  650. *(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
  651. *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
  652. break;
  653. case 180:
  654. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  655. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  656. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  657. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  658. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
  659. *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
  660. break;
  661. case 270:
  662. *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
  663. *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
  664. *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
  665. *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
  666. *(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
  667. *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
  668. break;
  669. }
  670. }
  671. }
  672. static void _Eff_position_s16lsb(int chan, void *stream, int len, void *udata)
  673. {
  674. /* 16 signed bits (lsb) * 2 channels. */
  675. volatile position_args *args = (volatile position_args *) udata;
  676. Sint16 *ptr = (Sint16 *) stream;
  677. int i;
  678. #if 0
  679. if (len % (sizeof(Sint16) * 2)) {
  680. fprintf(stderr,"Not an even number of frames! len=%d\n", len);
  681. return;
  682. }
  683. #endif
  684. for (i = 0; i < len; i += sizeof (Sint16) * 2) {
  685. Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
  686. args->left_f) * args->distance_f);
  687. Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
  688. args->right_f) * args->distance_f);
  689. if (args->room_angle == 180) {
  690. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  691. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  692. }
  693. else {
  694. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  695. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  696. }
  697. }
  698. }
  699. static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
  700. {
  701. /* 16 signed bits (lsb) * 4 channels. */
  702. volatile position_args *args = (volatile position_args *) udata;
  703. Sint16 *ptr = (Sint16 *) stream;
  704. int i;
  705. for (i = 0; i < len; i += sizeof (Sint16) * 4) {
  706. Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
  707. args->left_f) * args->distance_f);
  708. Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
  709. args->right_f) * args->distance_f);
  710. Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
  711. args->left_rear_f) * args->distance_f);
  712. Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
  713. args->right_rear_f) * args->distance_f);
  714. switch (args->room_angle) {
  715. case 0:
  716. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  717. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  718. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  719. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  720. break;
  721. case 90:
  722. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  723. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  724. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  725. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  726. break;
  727. case 180:
  728. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  729. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  730. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  731. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  732. break;
  733. case 270:
  734. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  735. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  736. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  737. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  738. break;
  739. }
  740. }
  741. }
  742. static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
  743. {
  744. /* 16 signed bits (lsb) * 6 channels. */
  745. volatile position_args *args = (volatile position_args *) udata;
  746. Sint16 *ptr = (Sint16 *) stream;
  747. int i;
  748. for (i = 0; i < len; i += sizeof (Sint16) * 6) {
  749. Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
  750. args->left_f) * args->distance_f);
  751. Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
  752. args->right_f) * args->distance_f);
  753. Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
  754. args->left_rear_f) * args->distance_f);
  755. Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
  756. args->right_rear_f) * args->distance_f);
  757. Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
  758. args->center_f) * args->distance_f);
  759. Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
  760. args->lfe_f) * args->distance_f);
  761. switch (args->room_angle) {
  762. case 0:
  763. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  764. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  765. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  766. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  767. *(ptr++) = (Sint16) SDL_SwapLE16(swapce);
  768. *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
  769. break;
  770. case 90:
  771. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  772. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  773. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  774. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  775. *(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
  776. *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
  777. break;
  778. case 180:
  779. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  780. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  781. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  782. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  783. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
  784. *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
  785. break;
  786. case 270:
  787. *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
  788. *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
  789. *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
  790. *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
  791. *(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
  792. *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
  793. break;
  794. }
  795. }
  796. }
  797. static void _Eff_position_u16msb(int chan, void *stream, int len, void *udata)
  798. {
  799. /* 16 signed bits (lsb) * 2 channels. */
  800. volatile position_args *args = (volatile position_args *) udata;
  801. Uint16 *ptr = (Uint16 *) stream;
  802. int i;
  803. for (i = 0; i < len; i += sizeof (Sint16) * 2) {
  804. Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
  805. Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
  806. Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
  807. * args->distance_f) + 32768);
  808. Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
  809. * args->distance_f) + 32768);
  810. if (args->room_angle == 180) {
  811. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  812. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  813. }
  814. else {
  815. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  816. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  817. }
  818. }
  819. }
  820. static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
  821. {
  822. /* 16 signed bits (lsb) * 4 channels. */
  823. volatile position_args *args = (volatile position_args *) udata;
  824. Uint16 *ptr = (Uint16 *) stream;
  825. int i;
  826. for (i = 0; i < len; i += sizeof (Sint16) * 4) {
  827. Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
  828. Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
  829. Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
  830. Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
  831. Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
  832. * args->distance_f) + 32768);
  833. Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
  834. * args->distance_f) + 32768);
  835. Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
  836. * args->distance_f) + 32768);
  837. Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
  838. * args->distance_f) + 32768);
  839. switch (args->room_angle) {
  840. case 0:
  841. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  842. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  843. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  844. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  845. break;
  846. case 90:
  847. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  848. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  849. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  850. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  851. break;
  852. case 180:
  853. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  854. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  855. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  856. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  857. break;
  858. case 270:
  859. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  860. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  861. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  862. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  863. break;
  864. }
  865. }
  866. }
  867. static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
  868. {
  869. /* 16 signed bits (lsb) * 6 channels. */
  870. volatile position_args *args = (volatile position_args *) udata;
  871. Uint16 *ptr = (Uint16 *) stream;
  872. int i;
  873. for (i = 0; i < len; i += sizeof (Sint16) * 6) {
  874. Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
  875. Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
  876. Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
  877. Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
  878. Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
  879. Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
  880. Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
  881. * args->distance_f) + 32768);
  882. Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
  883. * args->distance_f) + 32768);
  884. Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
  885. * args->distance_f) + 32768);
  886. Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
  887. * args->distance_f) + 32768);
  888. Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
  889. * args->distance_f) + 32768);
  890. Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
  891. * args->distance_f) + 32768);
  892. switch (args->room_angle) {
  893. case 0:
  894. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  895. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  896. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  897. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  898. *(ptr++) = (Uint16) SDL_SwapBE16(swapce);
  899. *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
  900. break;
  901. case 90:
  902. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  903. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  904. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  905. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  906. *(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
  907. *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
  908. break;
  909. case 180:
  910. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  911. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  912. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  913. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  914. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
  915. *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
  916. break;
  917. case 270:
  918. *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
  919. *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
  920. *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
  921. *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
  922. *(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
  923. *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
  924. break;
  925. }
  926. }
  927. }
  928. static void _Eff_position_s16msb(int chan, void *stream, int len, void *udata)
  929. {
  930. /* 16 signed bits (lsb) * 2 channels. */
  931. volatile position_args *args = (volatile position_args *) udata;
  932. Sint16 *ptr = (Sint16 *) stream;
  933. int i;
  934. for (i = 0; i < len; i += sizeof (Sint16) * 2) {
  935. Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
  936. args->left_f) * args->distance_f);
  937. Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
  938. args->right_f) * args->distance_f);
  939. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  940. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  941. }
  942. }
  943. static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
  944. {
  945. /* 16 signed bits (lsb) * 4 channels. */
  946. volatile position_args *args = (volatile position_args *) udata;
  947. Sint16 *ptr = (Sint16 *) stream;
  948. int i;
  949. for (i = 0; i < len; i += sizeof (Sint16) * 4) {
  950. Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
  951. args->left_f) * args->distance_f);
  952. Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
  953. args->right_f) * args->distance_f);
  954. Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
  955. args->left_rear_f) * args->distance_f);
  956. Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
  957. args->right_rear_f) * args->distance_f);
  958. switch (args->room_angle) {
  959. case 0:
  960. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  961. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  962. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  963. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  964. break;
  965. case 90:
  966. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  967. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  968. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  969. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  970. break;
  971. case 180:
  972. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  973. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  974. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  975. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  976. break;
  977. case 270:
  978. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  979. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  980. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  981. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  982. break;
  983. }
  984. }
  985. }
  986. static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
  987. {
  988. /* 16 signed bits (lsb) * 6 channels. */
  989. volatile position_args *args = (volatile position_args *) udata;
  990. Sint16 *ptr = (Sint16 *) stream;
  991. int i;
  992. for (i = 0; i < len; i += sizeof (Sint16) * 6) {
  993. Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
  994. args->left_f) * args->distance_f);
  995. Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
  996. args->right_f) * args->distance_f);
  997. Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
  998. args->left_rear_f) * args->distance_f);
  999. Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
  1000. args->right_rear_f) * args->distance_f);
  1001. Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
  1002. args->center_f) * args->distance_f);
  1003. Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
  1004. args->lfe_f) * args->distance_f);
  1005. switch (args->room_angle) {
  1006. case 0:
  1007. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  1008. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  1009. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  1010. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  1011. *(ptr++) = (Sint16) SDL_SwapBE16(swapce);
  1012. *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
  1013. break;
  1014. case 90:
  1015. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  1016. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  1017. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  1018. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  1019. *(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
  1020. *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
  1021. break;
  1022. case 180:
  1023. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  1024. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  1025. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  1026. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  1027. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
  1028. *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
  1029. break;
  1030. case 270:
  1031. *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
  1032. *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
  1033. *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
  1034. *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
  1035. *(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
  1036. *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
  1037. break;
  1038. }
  1039. }
  1040. }
  1041. static void init_position_args(position_args *args)
  1042. {
  1043. memset(args, '\0', sizeof (position_args));
  1044. args->in_use = 0;
  1045. args->room_angle = 0;
  1046. args->left_u8 = args->right_u8 = args->distance_u8 = 255;
  1047. args->left_f = args->right_f = args->distance_f = 1.0f;
  1048. args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
  1049. args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
  1050. Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
  1051. }
  1052. static position_args *get_position_arg(int channel)
  1053. {
  1054. void *rc;
  1055. int i;
  1056. if (channel < 0) {
  1057. if (pos_args_global == NULL) {
  1058. pos_args_global = malloc(sizeof (position_args));
  1059. if (pos_args_global == NULL) {
  1060. Mix_SetError("Out of memory");
  1061. return(NULL);
  1062. }
  1063. init_position_args(pos_args_global);
  1064. }
  1065. return(pos_args_global);
  1066. }
  1067. if (channel >= position_channels) {
  1068. rc = realloc(pos_args_array, (channel + 1) * sizeof (position_args *));
  1069. if (rc == NULL) {
  1070. Mix_SetError("Out of memory");
  1071. return(NULL);
  1072. }
  1073. pos_args_array = (position_args **) rc;
  1074. for (i = position_channels; i <= channel; i++) {
  1075. pos_args_array[i] = NULL;
  1076. }
  1077. position_channels = channel + 1;
  1078. }
  1079. if (pos_args_array[channel] == NULL) {
  1080. pos_args_array[channel] = (position_args *)malloc(sizeof(position_args));
  1081. if (pos_args_array[channel] == NULL) {
  1082. Mix_SetError("Out of memory");
  1083. return(NULL);
  1084. }
  1085. init_position_args(pos_args_array[channel]);
  1086. }
  1087. return(pos_args_array[channel]);
  1088. }
  1089. static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
  1090. {
  1091. Mix_EffectFunc_t f = NULL;
  1092. switch (format) {
  1093. case AUDIO_U8:
  1094. switch (channels) {
  1095. case 1:
  1096. case 2:
  1097. f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
  1098. _Eff_position_u8;
  1099. break;
  1100. case 4:
  1101. f = _Eff_position_u8_c4;
  1102. break;
  1103. case 6:
  1104. f = _Eff_position_u8_c6;
  1105. break;
  1106. }
  1107. break;
  1108. case AUDIO_S8:
  1109. switch (channels) {
  1110. case 1:
  1111. case 2:
  1112. f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
  1113. _Eff_position_s8;
  1114. break;
  1115. case 4:
  1116. f = _Eff_position_s8_c4;
  1117. break;
  1118. case 6:
  1119. f = _Eff_position_s8_c6;
  1120. break;
  1121. }
  1122. break;
  1123. case AUDIO_U16LSB:
  1124. switch (channels) {
  1125. case 1:
  1126. case 2:
  1127. f = _Eff_position_u16lsb;
  1128. break;
  1129. case 4:
  1130. f = _Eff_position_u16lsb_c4;
  1131. break;
  1132. case 6:
  1133. f = _Eff_position_u16lsb_c6;
  1134. break;
  1135. }
  1136. break;
  1137. case AUDIO_S16LSB:
  1138. switch (channels) {
  1139. case 1:
  1140. case 2:
  1141. f = _Eff_position_s16lsb;
  1142. break;
  1143. case 4:
  1144. f = _Eff_position_s16lsb_c4;
  1145. break;
  1146. case 6:
  1147. f = _Eff_position_s16lsb_c6;
  1148. break;
  1149. }
  1150. break;
  1151. case AUDIO_U16MSB:
  1152. switch (channels) {
  1153. case 1:
  1154. case 2:
  1155. f = _Eff_position_u16msb;
  1156. break;
  1157. case 4:
  1158. f = _Eff_position_u16msb_c4;
  1159. break;
  1160. case 6:
  1161. f = _Eff_position_u16msb_c6;
  1162. break;
  1163. }
  1164. break;
  1165. case AUDIO_S16MSB:
  1166. switch (channels) {
  1167. case 1:
  1168. case 2:
  1169. f = _Eff_position_s16msb;
  1170. break;
  1171. case 4:
  1172. f = _Eff_position_s16msb_c4;
  1173. break;
  1174. case 6:
  1175. f = _Eff_position_s16msb_c6;
  1176. break;
  1177. }
  1178. break;
  1179. default:
  1180. Mix_SetError("Unsupported audio format");
  1181. }
  1182. return(f);
  1183. }
  1184. static Uint8 speaker_amplitude[6];
  1185. static void set_amplitudes(int channels, int angle, int room_angle)
  1186. {
  1187. int left = 255, right = 255;
  1188. int left_rear = 255, right_rear = 255, center = 255;
  1189. angle = SDL_abs(angle) % 360; /* make angle between 0 an…