PageRenderTime 61ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/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
Possible License(s): LGPL-3.0, 0BSD, Apache-2.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, LGPL-2.0, BSD-3-Clause
  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 and 359. */
  1190. if (channels == 2)
  1191. {
  1192. /*
  1193. * We only attenuate by position if the angle falls on the far side
  1194. * of center; That is, an angle that's due north would not attenuate
  1195. * either channel. Due west attenuates the right channel to 0.0, and
  1196. * due east attenuates the left channel to 0.0. Slightly east of
  1197. * center attenuates the left channel a little, and the right channel
  1198. * not at all. I think of this as occlusion by one's own head. :)
  1199. *
  1200. * ...so, we split our angle circle into four quadrants...
  1201. */
  1202. if (angle < 90) {
  1203. left = 255 - ((int) (255.0f * (((float) angle) / 89.0f)));
  1204. } else if (angle < 180) {
  1205. left = (int) (255.0f * (((float) (angle - 90)) / 89.0f));
  1206. } else if (angle < 270) {
  1207. right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f)));
  1208. } else {
  1209. right = (int) (255.0f * (((float) (angle - 270)) / 89.0f));
  1210. }
  1211. }
  1212. if (channels == 4 || channels == 6)
  1213. {
  1214. /*
  1215. * An angle that's due north does not attenuate the center channel.
  1216. * An angle in the first quadrant, 0-90, does not attenuate the RF.
  1217. *
  1218. * ...so, we split our angle circle into 8 ...
  1219. *
  1220. * CE
  1221. * 0
  1222. * LF | RF
  1223. * |
  1224. * 270<-------|----------->90
  1225. * |
  1226. * LR | RR
  1227. * 180
  1228. *
  1229. */
  1230. if (angle < 45) {
  1231. left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
  1232. left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f)));
  1233. right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f)));
  1234. } else if (angle < 90) {
  1235. center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
  1236. left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
  1237. left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f)));
  1238. right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f)));
  1239. } else if (angle < 135) {
  1240. center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
  1241. left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f)));
  1242. right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
  1243. left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
  1244. } else if (angle < 180) {
  1245. center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f)));
  1246. left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f)));
  1247. right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
  1248. left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
  1249. } else if (angle < 225) {
  1250. center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f)));
  1251. left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
  1252. right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f)));
  1253. right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
  1254. } else if (angle < 270) {
  1255. center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
  1256. left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
  1257. right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f)));
  1258. right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
  1259. } else if (angle < 315) {
  1260. center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
  1261. right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
  1262. left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
  1263. right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f)));
  1264. } else {
  1265. right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
  1266. left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
  1267. right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f)));
  1268. }
  1269. }
  1270. if (left < 0) left = 0; if (left > 255) left = 255;
  1271. if (right < 0) right = 0; if (right > 255) right = 255;
  1272. if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255;
  1273. if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255;
  1274. if (center < 0) center = 0; if (center > 255) center = 255;
  1275. if (room_angle == 90) {
  1276. speaker_amplitude[0] = (Uint8)left_rear;
  1277. speaker_amplitude[1] = (Uint8)left;
  1278. speaker_amplitude[2] = (Uint8)right_rear;
  1279. speaker_amplitude[3] = (Uint8)right;
  1280. }
  1281. else if (room_angle == 180) {
  1282. if (channels == 2) {
  1283. speaker_amplitude[0] = (Uint8)right;
  1284. speaker_amplitude[1] = (Uint8)left;
  1285. }
  1286. else {
  1287. speaker_amplitude[0] = (Uint8)right_rear;
  1288. speaker_amplitude[1] = (Uint8)left_rear;
  1289. speaker_amplitude[2] = (Uint8)right;
  1290. speaker_amplitude[3] = (Uint8)left;
  1291. }
  1292. }
  1293. else if (room_angle == 270) {
  1294. speaker_amplitude[0] = (Uint8)right;
  1295. speaker_amplitude[1] = (Uint8)right_rear;
  1296. speaker_amplitude[2] = (Uint8)left;
  1297. speaker_amplitude[3] = (Uint8)left_rear;
  1298. }
  1299. else {
  1300. speaker_amplitude[0] = (Uint8)left;
  1301. speaker_amplitude[1] = (Uint8)right;
  1302. speaker_amplitude[2] = (Uint8)left_rear;
  1303. speaker_amplitude[3] = (Uint8)right_rear;
  1304. }
  1305. speaker_amplitude[4] = (Uint8)center;
  1306. speaker_amplitude[5] = 255;
  1307. }
  1308. int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
  1309. int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
  1310. {
  1311. Mix_EffectFunc_t f = NULL;
  1312. int channels;
  1313. Uint16 format;
  1314. position_args *args = NULL;
  1315. int retval = 1;
  1316. Mix_QuerySpec(NULL, &format, &channels);
  1317. if (channels != 2 && channels != 4 && channels != 6) /* it's a no-op; we call that successful. */
  1318. return(1);
  1319. if (channels > 2) {
  1320. /* left = right = 255 => angle = 0, to unregister effect as when channels = 2 */
  1321. /* left = 255 => angle = -90; left = 0 => angle = +89 */
  1322. int angle = 0;
  1323. if ((left != 255) || (right != 255)) {
  1324. angle = (int)left;
  1325. angle = 127 - angle;
  1326. angle = -angle;
  1327. angle = angle * 90 / 128; /* Make it larger for more effect? */
  1328. }
  1329. return( Mix_SetPosition(channel, angle, 0) );
  1330. }
  1331. f = get_position_effect_func(format, channels);
  1332. if (f == NULL)
  1333. return(0);
  1334. SDL_LockAudio();
  1335. args = get_position_arg(channel);
  1336. if (!args) {
  1337. SDL_UnlockAudio();
  1338. return(0);
  1339. }
  1340. /* it's a no-op; unregister the effect, if it's registered. */
  1341. if ((args->distance_u8 == 255) && (left == 255) && (right == 255)) {
  1342. if (args->in_use) {
  1343. retval = _Mix_UnregisterEffect_locked(channel, f);
  1344. SDL_UnlockAudio();
  1345. return(retval);
  1346. } else {
  1347. SDL_UnlockAudio();
  1348. return(1);
  1349. }
  1350. }
  1351. args->left_u8 = left;
  1352. args->left_f = ((float) left) / 255.0f;
  1353. args->right_u8 = right;
  1354. args->right_f = ((float) right) / 255.0f;
  1355. args->room_angle = 0;
  1356. if (!args->in_use) {
  1357. args->in_use = 1;
  1358. retval=_Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void*)args);
  1359. }
  1360. SDL_UnlockAudio();
  1361. return(retval);
  1362. }
  1363. int Mix_SetDistance(int channel, Uint8 distance)
  1364. {
  1365. Mix_EffectFunc_t f = NULL;
  1366. Uint16 format;
  1367. position_args *args = NULL;
  1368. int channels;
  1369. int retval = 1;
  1370. Mix_QuerySpec(NULL, &format, &channels);
  1371. f = get_position_effect_func(format, channels);
  1372. if (f == NULL)
  1373. return(0);
  1374. SDL_LockAudio();
  1375. args = get_position_arg(channel);
  1376. if (!args) {
  1377. SDL_UnlockAudio();
  1378. return(0);
  1379. }
  1380. distance = 255 - distance; /* flip it to our scale. */
  1381. /* it's a no-op; unregister the effect, if it's registered. */
  1382. if ((distance == 255) && (args->left_u8 == 255) && (args->right_u8 == 255)) {
  1383. if (args->in_use) {
  1384. retval = _Mix_UnregisterEffect_locked(channel, f);
  1385. SDL_UnlockAudio();
  1386. return(retval);
  1387. } else {
  1388. SDL_UnlockAudio();
  1389. return(1);
  1390. }
  1391. }
  1392. args->distance_u8 = distance;
  1393. args->distance_f = ((float) distance) / 255.0f;
  1394. if (!args->in_use) {
  1395. args->in_use = 1;
  1396. retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
  1397. }
  1398. SDL_UnlockAudio();
  1399. return(retval);
  1400. }
  1401. int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
  1402. {
  1403. Mix_EffectFunc_t f = NULL;
  1404. Uint16 format;
  1405. int channels;
  1406. position_args *args = NULL;
  1407. Sint16 room_angle = 0;
  1408. int retval = 1;
  1409. Mix_QuerySpec(NULL, &format, &channels);
  1410. f = get_position_effect_func(format, channels);
  1411. if (f == NULL)
  1412. return(0);
  1413. angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */
  1414. SDL_LockAudio();
  1415. args = get_position_arg(channel);
  1416. if (!args) {
  1417. SDL_UnlockAudio();
  1418. return(0);
  1419. }
  1420. /* it's a no-op; unregister the effect, if it's registered. */
  1421. if ((!distance) && (!angle)) {
  1422. if (args->in_use) {
  1423. retval = _Mix_UnregisterEffect_locked(channel, f);
  1424. SDL_UnlockAudio();
  1425. return(retval);
  1426. } else {
  1427. SDL_UnlockAudio();
  1428. return(1);
  1429. }
  1430. }
  1431. if (channels == 2)
  1432. {
  1433. if (angle > 180)
  1434. room_angle = 180; /* exchange left and right channels */
  1435. else room_angle = 0;
  1436. }
  1437. if (channels == 4 || channels == 6)
  1438. {
  1439. if (angle > 315) room_angle = 0;
  1440. else if (angle > 225) room_angle = 270;
  1441. else if (angle > 135) room_angle = 180;
  1442. else if (angle > 45) room_angle = 90;
  1443. else room_angle = 0;
  1444. }
  1445. distance = 255 - distance; /* flip it to scale Mix_SetDistance() uses. */
  1446. set_amplitudes(channels, angle, room_angle);
  1447. args->left_u8 = speaker_amplitude[0];
  1448. args->left_f = ((float) speaker_amplitude[0]) / 255.0f;
  1449. args->right_u8 = speaker_amplitude[1];
  1450. args->right_f = ((float) speaker_amplitude[1]) / 255.0f;
  1451. args->left_rear_u8 = speaker_amplitude[2];
  1452. args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f;
  1453. args->right_rear_u8 = speaker_amplitude[3];
  1454. args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f;
  1455. args->center_u8 = speaker_amplitude[4];
  1456. args->center_f = ((float) speaker_amplitude[4]) / 255.0f;
  1457. args->lfe_u8 = speaker_amplitude[5];
  1458. args->lfe_f = ((float) speaker_amplitude[5]) / 255.0f;
  1459. args->distance_u8 = distance;
  1460. args->distance_f = ((float) distance) / 255.0f;
  1461. args->room_angle = room_angle;
  1462. if (!args->in_use) {
  1463. args->in_use = 1;
  1464. retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
  1465. }
  1466. SDL_UnlockAudio();
  1467. return(retval);
  1468. }
  1469. /* end of effects_position.c ... */