1 /* 2 SDL_mixer: An audio mixer library based on the SDL library 3 Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20 21 This file by Ryan C. Gordon (icculus@icculus.org) 22 23 These are some internally supported special effects that use SDL_mixer's 24 effect callback API. They are meant for speed over quality. :) 25 */ 26 27 /* $Id$ */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #include "SDL.h" 34 #include "SDL_mixer.h" 35 #include "SDL_endian.h" 36 37 #define __MIX_INTERNAL_EFFECT__ 38 #include "effects_internal.h" 39 40 /* profile code: 41 #include <sys/time.h> 42 #include <unistd.h> 43 struct timeval tv1; 44 struct timeval tv2; 45 46 gettimeofday(&tv1, NULL); 47 48 ... do your thing here ... 49 50 gettimeofday(&tv2, NULL); 51 printf("%ld\n", tv2.tv_usec - tv1.tv_usec); 52 */ 53 54 55 /* 56 * Positional effects...panning, distance attenuation, etc. 57 */ 58 59 typedef struct _Eff_positionargs 60 { 61 volatile float left_f; 62 volatile float right_f; 63 volatile Uint8 left_u8; 64 volatile Uint8 right_u8; 65 volatile float left_rear_f; 66 volatile float right_rear_f; 67 volatile float center_f; 68 volatile float lfe_f; 69 volatile Uint8 left_rear_u8; 70 volatile Uint8 right_rear_u8; 71 volatile Uint8 center_u8; 72 volatile Uint8 lfe_u8; 73 volatile float distance_f; 74 volatile Uint8 distance_u8; 75 volatile Sint16 room_angle; 76 volatile int in_use; 77 volatile int channels; 78 } position_args; 79 80 static position_args **pos_args_array = NULL; 81 static position_args *pos_args_global = NULL; 82 static int position_channels = 0; 83 84 void _Eff_PositionDeinit(void) 85 { 86 int i; 87 for (i = 0; i < position_channels; i++) { 88 SDL_free(pos_args_array[i]); 89 } 90 91 position_channels = 0; 92 93 SDL_free(pos_args_global); 94 pos_args_global = NULL; 95 SDL_free(pos_args_array); 96 pos_args_array = NULL; 97 } 98 99 100 /* This just frees up the callback-specific data. */ 101 static void _Eff_PositionDone(int channel, void *udata) 102 { 103 if (channel < 0) { 104 if (pos_args_global != NULL) { 105 SDL_free(pos_args_global); 106 pos_args_global = NULL; 107 } 108 } 109 110 else if (pos_args_array[channel] != NULL) { 111 SDL_free(pos_args_array[channel]); 112 pos_args_array[channel] = NULL; 113 } 114 } 115 116 117 static void _Eff_position_u8(int chan, void *stream, int len, void *udata) 118 { 119 volatile position_args *args = (volatile position_args *) udata; 120 Uint8 *ptr = (Uint8 *) stream; 121 int i; 122 123 /* 124 * if there's only a mono channnel (the only way we wouldn't have 125 * a len divisible by 2 here), then left_f and right_f are always 126 * 1.0, and are therefore throwaways. 127 */ 128 if (len % sizeof (Uint16) != 0) { 129 *ptr = (Uint8) (((float) *ptr) * args->distance_f); 130 ptr++; 131 len--; 132 } 133 134 if (args->room_angle == 180) 135 for (i = 0; i < len; i += sizeof (Uint8) * 2) { 136 /* must adjust the sample so that 0 is the center */ 137 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 138 * args->right_f) * args->distance_f) + 128); 139 ptr++; 140 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 141 * args->left_f) * args->distance_f) + 128); 142 ptr++; 143 } 144 else for (i = 0; i < len; i += sizeof (Uint8) * 2) { 145 /* must adjust the sample so that 0 is the center */ 146 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 147 * args->left_f) * args->distance_f) + 128); 148 ptr++; 149 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 150 * args->right_f) * args->distance_f) + 128); 151 ptr++; 152 } 153 } 154 static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata) 155 { 156 volatile position_args *args = (volatile position_args *) udata; 157 Uint8 *ptr = (Uint8 *) stream; 158 int i; 159 160 /* 161 * if there's only a mono channnel (the only way we wouldn't have 162 * a len divisible by 2 here), then left_f and right_f are always 163 * 1.0, and are therefore throwaways. 164 */ 165 if (len % sizeof (Uint16) != 0) { 166 *ptr = (Uint8) (((float) *ptr) * args->distance_f); 167 ptr++; 168 len--; 169 } 170 171 if (args->room_angle == 0) 172 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 173 /* must adjust the sample so that 0 is the center */ 174 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 175 * args->left_f) * args->distance_f) + 128); 176 ptr++; 177 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 178 * args->right_f) * args->distance_f) + 128); 179 ptr++; 180 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 181 * args->left_rear_f) * args->distance_f) + 128); 182 ptr++; 183 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 184 * args->right_rear_f) * args->distance_f) + 128); 185 ptr++; 186 } 187 else if (args->room_angle == 90) 188 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 189 /* must adjust the sample so that 0 is the center */ 190 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 191 * args->right_f) * args->distance_f) + 128); 192 ptr++; 193 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 194 * args->right_rear_f) * args->distance_f) + 128); 195 ptr++; 196 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 197 * args->left_f) * args->distance_f) + 128); 198 ptr++; 199 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 200 * args->left_rear_f) * args->distance_f) + 128); 201 ptr++; 202 } 203 else if (args->room_angle == 180) 204 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 205 /* must adjust the sample so that 0 is the center */ 206 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 207 * args->right_rear_f) * args->distance_f) + 128); 208 ptr++; 209 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 210 * args->left_rear_f) * args->distance_f) + 128); 211 ptr++; 212 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 213 * args->right_f) * args->distance_f) + 128); 214 ptr++; 215 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 216 * args->left_f) * args->distance_f) + 128); 217 ptr++; 218 } 219 else if (args->room_angle == 270) 220 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 221 /* must adjust the sample so that 0 is the center */ 222 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 223 * args->left_rear_f) * args->distance_f) + 128); 224 ptr++; 225 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 226 * args->left_f) * args->distance_f) + 128); 227 ptr++; 228 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 229 * args->right_rear_f) * args->distance_f) + 128); 230 ptr++; 231 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 232 * args->right_f) * args->distance_f) + 128); 233 ptr++; 234 } 235 } 236 237 238 static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata) 239 { 240 volatile position_args *args = (volatile position_args *) udata; 241 Uint8 *ptr = (Uint8 *) stream; 242 int i; 243 244 /* 245 * if there's only a mono channnel (the only way we wouldn't have 246 * a len divisible by 2 here), then left_f and right_f are always 247 * 1.0, and are therefore throwaways. 248 */ 249 if (len % sizeof (Uint16) != 0) { 250 *ptr = (Uint8) (((float) *ptr) * args->distance_f); 251 ptr++; 252 len--; 253 } 254 255 if (args->room_angle == 0) 256 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 257 /* must adjust the sample so that 0 is the center */ 258 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 259 * args->left_f) * args->distance_f) + 128); 260 ptr++; 261 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 262 * args->right_f) * args->distance_f) + 128); 263 ptr++; 264 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 265 * args->left_rear_f) * args->distance_f) + 128); 266 ptr++; 267 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 268 * args->right_rear_f) * args->distance_f) + 128); 269 ptr++; 270 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 271 * args->center_f) * args->distance_f) + 128); 272 ptr++; 273 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 274 * args->lfe_f) * args->distance_f) + 128); 275 ptr++; 276 } 277 else if (args->room_angle == 90) 278 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 279 /* must adjust the sample so that 0 is the center */ 280 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 281 * args->right_f) * args->distance_f) + 128); 282 ptr++; 283 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 284 * args->right_rear_f) * args->distance_f) + 128); 285 ptr++; 286 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 287 * args->left_f) * args->distance_f) + 128); 288 ptr++; 289 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 290 * args->left_rear_f) * args->distance_f) + 128); 291 ptr++; 292 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 293 * args->right_rear_f) * args->distance_f/2) + 128) 294 + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 295 * args->right_f) * args->distance_f/2) + 128); 296 ptr++; 297 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 298 * args->lfe_f) * args->distance_f) + 128); 299 ptr++; 300 } 301 else if (args->room_angle == 180) 302 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 303 /* must adjust the sample so that 0 is the center */ 304 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 305 * args->right_rear_f) * args->distance_f) + 128); 306 ptr++; 307 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 308 * args->left_rear_f) * args->distance_f) + 128); 309 ptr++; 310 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 311 * args->right_f) * args->distance_f) + 128); 312 ptr++; 313 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 314 * args->left_f) * args->distance_f) + 128); 315 ptr++; 316 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 317 * args->right_rear_f) * args->distance_f/2) + 128) 318 + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 319 * args->left_rear_f) * args->distance_f/2) + 128); 320 ptr++; 321 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 322 * args->lfe_f) * args->distance_f) + 128); 323 ptr++; 324 } 325 else if (args->room_angle == 270) 326 for (i = 0; i < len; i += sizeof (Uint8) * 6) { 327 /* must adjust the sample so that 0 is the center */ 328 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 329 * args->left_rear_f) * args->distance_f) + 128); 330 ptr++; 331 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 332 * args->left_f) * args->distance_f) + 128); 333 ptr++; 334 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 335 * args->right_rear_f) * args->distance_f) + 128); 336 ptr++; 337 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 338 * args->right_f) * args->distance_f) + 128); 339 ptr++; 340 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 341 * args->left_f) * args->distance_f/2) + 128) 342 + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 343 * args->left_rear_f) * args->distance_f/2) + 128); 344 ptr++; 345 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 346 * args->lfe_f) * args->distance_f) + 128); 347 ptr++; 348 } 349 } 350 351 352 /* 353 * This one runs about 10.1 times faster than the non-table version, with 354 * no loss in quality. It does, however, require 64k of memory for the 355 * lookup table. Also, this will only update position information once per 356 * call; the non-table version always checks the arguments for each sample, 357 * in case the user has called Mix_SetPanning() or whatnot again while this 358 * callback is running. 359 */ 360 static void _Eff_position_table_u8(int chan, void *stream, int len, void *udata) 361 { 362 volatile position_args *args = (volatile position_args *) udata; 363 Uint8 *ptr = (Uint8 *) stream; 364 Uint32 *p; 365 int i; 366 Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8); 367 Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8); 368 Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8); 369 370 if (args->room_angle == 180) { 371 Uint8 *temp = l; 372 l = r; 373 r = temp; 374 } 375 /* 376 * if there's only a mono channnel, then l[] and r[] are always 377 * volume 255, and are therefore throwaways. Still, we have to 378 * be sure not to overrun the audio buffer... 379 */ 380 while (len % sizeof (Uint32) != 0) { 381 *ptr = d[l[*ptr]]; 382 ptr++; 383 if (args->channels > 1) { 384 *ptr = d[r[*ptr]]; 385 ptr++; 386 } 387 len -= args->channels; 388 } 389 390 p = (Uint32 *) ptr; 391 392 for (i = 0; i < len; i += sizeof (Uint32)) { 393 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN) 394 *p = (d[l[(*p & 0xFF000000) >> 24]] << 24) | 395 (d[r[(*p & 0x00FF0000) >> 16]] << 16) | 396 (d[l[(*p & 0x0000FF00) >> 8]] << 8) | 397 (d[r[(*p & 0x000000FF) ]] ) ; 398 #else 399 *p = (d[r[(*p & 0xFF000000) >> 24]] << 24) | 400 (d[l[(*p & 0x00FF0000) >> 16]] << 16) | 401 (d[r[(*p & 0x0000FF00) >> 8]] << 8) | 402 (d[l[(*p & 0x000000FF) ]] ) ; 403 #endif 404 ++p; 405 } 406 } 407 408 409 static void _Eff_position_s8(int chan, void *stream, int len, void *udata) 410 { 411 volatile position_args *args = (volatile position_args *) udata; 412 Sint8 *ptr = (Sint8 *) stream; 413 int i; 414 415 /* 416 * if there's only a mono channnel (the only way we wouldn't have 417 * a len divisible by 2 here), then left_f and right_f are always 418 * 1.0, and are therefore throwaways. 419 */ 420 if (len % sizeof (Sint16) != 0) { 421 *ptr = (Sint8) (((float) *ptr) * args->distance_f); 422 ptr++; 423 len--; 424 } 425 426 if (args->room_angle == 180) 427 for (i = 0; i < len; i += sizeof (Sint8) * 2) { 428 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); 429 ptr++; 430 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); 431 ptr++; 432 } 433 else 434 for (i = 0; i < len; i += sizeof (Sint8) * 2) { 435 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); 436 ptr++; 437 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); 438 ptr++; 439 } 440 } 441 static void _Eff_position_s8_c4(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 /* 448 * if there's only a mono channnel (the only way we wouldn't have 449 * a len divisible by 2 here), then left_f and right_f are always 450 * 1.0, and are therefore throwaways. 451 */ 452 if (len % sizeof (Sint16) != 0) { 453 *ptr = (Sint8) (((float) *ptr) * args->distance_f); 454 ptr++; 455 len--; 456 } 457 458 for (i = 0; i < len; i += sizeof (Sint8) * 4) { 459 switch (args->room_angle) { 460 case 0: 461 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 462 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 463 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 464 *ptr = (Sint8)((((float) *ptr) * args->right_rear_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 break; 472 case 180: 473 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++; 474 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 475 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 476 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 477 break; 478 case 270: 479 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 480 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 481 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++; 482 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 483 break; 484 } 485 } 486 } 487 static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata) 488 { 489 volatile position_args *args = (volatile position_args *) udata; 490 Sint8 *ptr = (Sint8 *) stream; 491 int i; 492 493 /* 494 * if there's only a mono channnel (the only way we wouldn't have 495 * a len divisible by 2 here), then left_f and right_f are always 496 * 1.0, and are therefore throwaways. 497 */ 498 if (len % sizeof (Sint16) != 0) { 499 *ptr = (Sint8) (((float) *ptr) * args->distance_f); 500 ptr++; 501 len--; 502 } 503 504 for (i = 0; i < len; i += sizeof (Sint8) * 6) { 505 switch (args->room_angle) { 506 case 0: 507 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 508 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 509 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 510 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++; 511 *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++; 512 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++; 513 break; 514 case 90: 515 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 516 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++; 517 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 518 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 519 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2) 520 + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++; 521 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++; 522 break; 523 case 180: 524 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++; 525 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 526 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 527 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 528 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2) 529 + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++; 530 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++; 531 break; 532 case 270: 533 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++; 534 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++; 535 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++; 536 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++; 537 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2) 538 + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++; 539 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++; 540 break; 541 } 542 } 543 } 544 545 546 /* 547 * This one runs about 10.1 times faster than the non-table version, with 548 * no loss in quality. It does, however, require 64k of memory for the 549 * lookup table. Also, this will only update position information once per 550 * call; the non-table version always checks the arguments for each sample, 551 * in case the user has called Mix_SetPanning() or whatnot again while this 552 * callback is running. 553 */ 554 static void _Eff_position_table_s8(int chan, void *stream, int len, void *udata) 555 { 556 volatile position_args *args = (volatile position_args *) udata; 557 Sint8 *ptr = (Sint8 *) stream; 558 Uint32 *p; 559 int i; 560 Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8); 561 Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8); 562 Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8); 563 564 if (args->room_angle == 180) { 565 Sint8 *temp = l; 566 l = r; 567 r = temp; 568 } 569 570 571 while (len % sizeof (Uint32) != 0) { 572 *ptr = d[l[*ptr]]; 573 ptr++; 574 if (args->channels > 1) { 575 *ptr = d[r[*ptr]]; 576 ptr++; 577 } 578 len -= args->channels; 579 } 580 581 p = (Uint32 *) ptr; 582 583 for (i = 0; i < len; i += sizeof (Uint32)) { 584 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN) 585 *p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) | 586 (d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) | 587 (d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) | 588 (d[r[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ; 589 #else 590 *p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) | 591 (d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) | 592 (d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) | 593 (d[l[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ; 594 #endif 595 ++p; 596 } 597 598 599 } 600 601 602 /* !!! FIXME : Optimize the code for 16-bit samples? */ 603 604 static void _Eff_position_u16lsb(int chan, void *stream, int len, void *udata) 605 { 606 volatile position_args *args = (volatile position_args *) udata; 607 Uint16 *ptr = (Uint16 *) stream; 608 int i; 609 610 for (i = 0; i < len; i += sizeof (Uint16) * 2) { 611 Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768); 612 Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768); 613 614 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f) 615 * args->distance_f) + 32768); 616 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f) 617 * args->distance_f) + 32768); 618 619 if (args->room_angle == 180) { 620 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 621 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 622 } 623 else { 624 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 625 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 626 } 627 } 628 } 629 static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata) 630 { 631 volatile position_args *args = (volatile position_args *) udata; 632 Uint16 *ptr = (Uint16 *) stream; 633 int i; 634 635 for (i = 0; i < len; i += sizeof (Uint16) * 4) { 636 Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768); 637 Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768); 638 Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768); 639 Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768); 640 641 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f) 642 * args->distance_f) + 32768); 643 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f) 644 * args->distance_f) + 32768); 645 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f) 646 * args->distance_f) + 32768); 647 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f) 648 * args->distance_f) + 32768); 649 650 switch (args->room_angle) { 651 case 0: 652 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 653 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 654 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 655 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 656 break; 657 case 90: 658 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 659 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 660 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 661 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 662 break; 663 case 180: 664 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 665 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 666 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 667 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 668 break; 669 case 270: 670 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 671 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 672 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 673 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 674 break; 675 } 676 } 677 } 678 static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata) 679 { 680 volatile position_args *args = (volatile position_args *) udata; 681 Uint16 *ptr = (Uint16 *) stream; 682 int i; 683 684 for (i = 0; i < len; i += sizeof (Uint16) * 6) { 685 Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768); 686 Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768); 687 Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768); 688 Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768); 689 Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768); 690 Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768); 691 692 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f) 693 * args->distance_f) + 32768); 694 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f) 695 * args->distance_f) + 32768); 696 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f) 697 * args->distance_f) + 32768); 698 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f) 699 * args->distance_f) + 32768); 700 Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f) 701 * args->distance_f) + 32768); 702 Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f) 703 * args->distance_f) + 32768); 704 705 switch (args->room_angle) { 706 case 0: 707 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 708 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 709 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 710 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 711 *(ptr++) = (Uint16) SDL_SwapLE16(swapce); 712 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf); 713 break; 714 case 90: 715 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 716 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 717 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 718 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 719 *(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2; 720 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf); 721 break; 722 case 180: 723 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 724 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 725 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 726 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 727 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2; 728 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf); 729 break; 730 case 270: 731 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr); 732 *(ptr++) = (Uint16) SDL_SwapLE16(swapl); 733 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr); 734 *(ptr++) = (Uint16) SDL_SwapLE16(swapr); 735 *(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2; 736 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf); 737 break; 738 } 739 } 740 } 741 742 static void _Eff_position_s16lsb(int chan, void *stream, int len, void *udata) 743 { 744 /* 16 signed bits (lsb) * 2 channels. */ 745 volatile position_args *args = (volatile position_args *) udata; 746 Sint16 *ptr = (Sint16 *) stream; 747 int i; 748 749 #if 0 750 if (len % (sizeof(Sint16) * 2)) { 751 fprintf(stderr,"Not an even number of frames! len=%d\n", len); 752 return; 753 } 754 #endif 755 756 for (i = 0; i < len; i += sizeof (Sint16) * 2) { 757 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) * 758 args->left_f) * args->distance_f); 759 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) * 760 args->right_f) * args->distance_f); 761 if (args->room_angle == 180) { 762 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 763 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 764 } 765 else { 766 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 767 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 768 } 769 } 770 } 771 static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata) 772 { 773 /* 16 signed bits (lsb) * 4 channels. */ 774 volatile position_args *args = (volatile position_args *) udata; 775 Sint16 *ptr = (Sint16 *) stream; 776 int i; 777 778 for (i = 0; i < len; i += sizeof (Sint16) * 4) { 779 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) * 780 args->left_f) * args->distance_f); 781 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) * 782 args->right_f) * args->distance_f); 783 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) * 784 args->left_rear_f) * args->distance_f); 785 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) * 786 args->right_rear_f) * args->distance_f); 787 switch (args->room_angle) { 788 case 0: 789 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 790 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 791 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 792 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 793 break; 794 case 90: 795 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 796 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 797 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 798 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 799 break; 800 case 180: 801 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 802 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 803 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 804 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 805 break; 806 case 270: 807 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 808 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 809 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 810 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 811 break; 812 } 813 } 814 } 815 816 static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata) 817 { 818 /* 16 signed bits (lsb) * 6 channels. */ 819 volatile position_args *args = (volatile position_args *) udata; 820 Sint16 *ptr = (Sint16 *) stream; 821 int i; 822 823 for (i = 0; i < len; i += sizeof (Sint16) * 6) { 824 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) * 825 args->left_f) * args->distance_f); 826 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) * 827 args->right_f) * args->distance_f); 828 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) * 829 args->left_rear_f) * args->distance_f); 830 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) * 831 args->right_rear_f) * args->distance_f); 832 Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) * 833 args->center_f) * args->distance_f); 834 Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) * 835 args->lfe_f) * args->distance_f); 836 switch (args->room_angle) { 837 case 0: 838 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 839 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 840 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 841 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 842 *(ptr++) = (Sint16) SDL_SwapLE16(swapce); 843 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf); 844 break; 845 case 90: 846 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 847 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 848 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 849 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 850 *(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2; 851 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf); 852 break; 853 case 180: 854 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 855 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 856 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 857 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 858 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2; 859 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf); 860 break; 861 case 270: 862 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr); 863 *(ptr++) = (Sint16) SDL_SwapLE16(swapl); 864 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr); 865 *(ptr++) = (Sint16) SDL_SwapLE16(swapr); 866 *(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2; 867 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf); 868 break; 869 } 870 } 871 } 872 873 static void _Eff_position_u16msb(int chan, void *stream, int len, void *udata) 874 { 875 /* 16 signed bits (lsb) * 2 channels. */ 876 volatile position_args *args = (volatile position_args *) udata; 877 Uint16 *ptr = (Uint16 *) stream; 878 int i; 879 880 for (i = 0; i < len; i += sizeof (Sint16) * 2) { 881 Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768); 882 Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768); 883 884 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f) 885 * args->distance_f) + 32768); 886 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f) 887 * args->distance_f) + 32768); 888 889 if (args->room_angle == 180) { 890 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 891 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 892 } 893 else { 894 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 895 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 896 } 897 } 898 } 899 static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata) 900 { 901 /* 16 signed bits (lsb) * 4 channels. */ 902 volatile position_args *args = (volatile position_args *) udata; 903 Uint16 *ptr = (Uint16 *) stream; 904 int i; 905 906 for (i = 0; i < len; i += sizeof (Sint16) * 4) { 907 Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768); 908 Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768); 909 Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768); 910 Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768); 911 912 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f) 913 * args->distance_f) + 32768); 914 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f) 915 * args->distance_f) + 32768); 916 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f) 917 * args->distance_f) + 32768); 918 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f) 919 * args->distance_f) + 32768); 920 921 switch (args->room_angle) { 922 case 0: 923 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 924 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 925 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 926 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 927 break; 928 case 90: 929 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 930 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 931 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 932 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 933 break; 934 case 180: 935 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 936 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 937 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 938 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 939 break; 940 case 270: 941 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 942 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 943 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 944 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 945 break; 946 } 947 } 948 } 949 static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata) 950 { 951 /* 16 signed bits (lsb) * 6 channels. */ 952 volatile position_args *args = (volatile position_args *) udata; 953 Uint16 *ptr = (Uint16 *) stream; 954 int i; 955 956 for (i = 0; i < len; i += sizeof (Sint16) * 6) { 957 Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768); 958 Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768); 959 Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768); 960 Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768); 961 Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768); 962 Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768); 963 964 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f) 965 * args->distance_f) + 32768); 966 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f) 967 * args->distance_f) + 32768); 968 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f) 969 * args->distance_f) + 32768); 970 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f) 971 * args->distance_f) + 32768); 972 Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f) 973 * args->distance_f) + 32768); 974 Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f) 975 * args->distance_f) + 32768); 976 977 switch (args->room_angle) { 978 case 0: 979 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 980 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 981 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 982 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 983 *(ptr++) = (Uint16) SDL_SwapBE16(swapce); 984 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf); 985 break; 986 case 90: 987 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 988 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 989 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 990 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 991 *(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2; 992 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf); 993 break; 994 case 180: 995 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 996 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 997 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 998 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 999 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2; 1000 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf); 1001 break; 1002 case 270: 1003 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr); 1004 *(ptr++) = (Uint16) SDL_SwapBE16(swapl); 1005 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr); 1006 *(ptr++) = (Uint16) SDL_SwapBE16(swapr); 1007 *(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2; 1008 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf); 1009 break; 1010 } 1011 } 1012 } 1013 1014 static void _Eff_position_s16msb(int chan, void *stream, int len, void *udata) 1015 { 1016 /* 16 signed bits (lsb) * 2 channels. */ 1017 volatile position_args *args = (volatile position_args *) udata; 1018 Sint16 *ptr = (Sint16 *) stream; 1019 int i; 1020 1021 for (i = 0; i < len; i += sizeof (Sint16) * 2) { 1022 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) * 1023 args->left_f) * args->distance_f); 1024 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) * 1025 args->right_f) * args->distance_f); 1026 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1027 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1028 } 1029 } 1030 static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata) 1031 { 1032 /* 16 signed bits (lsb) * 4 channels. */ 1033 volatile position_args *args = (volatile position_args *) udata; 1034 Sint16 *ptr = (Sint16 *) stream; 1035 int i; 1036 1037 for (i = 0; i < len; i += sizeof (Sint16) * 4) { 1038 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) * 1039 args->left_f) * args->distance_f); 1040 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) * 1041 args->right_f) * args->distance_f); 1042 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) * 1043 args->left_rear_f) * args->distance_f); 1044 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) * 1045 args->right_rear_f) * args->distance_f); 1046 switch (args->room_angle) { 1047 case 0: 1048 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1049 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1050 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1051 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1052 break; 1053 case 90: 1054 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1055 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1056 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1057 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1058 break; 1059 case 180: 1060 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1061 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1062 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1063 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1064 break; 1065 case 270: 1066 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1067 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1068 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1069 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1070 break; 1071 } 1072 } 1073 } 1074 static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata) 1075 { 1076 /* 16 signed bits (lsb) * 6 channels. */ 1077 volatile position_args *args = (volatile position_args *) udata; 1078 Sint16 *ptr = (Sint16 *) stream; 1079 int i; 1080 1081 for (i = 0; i < len; i += sizeof (Sint16) * 6) { 1082 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) * 1083 args->left_f) * args->distance_f); 1084 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) * 1085 args->right_f) * args->distance_f); 1086 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) * 1087 args->left_rear_f) * args->distance_f); 1088 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) * 1089 args->right_rear_f) * args->distance_f); 1090 Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) * 1091 args->center_f) * args->distance_f); 1092 Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) * 1093 args->lfe_f) * args->distance_f); 1094 1095 switch (args->room_angle) { 1096 case 0: 1097 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1098 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1099 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1100 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1101 *(ptr++) = (Sint16) SDL_SwapBE16(swapce); 1102 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf); 1103 break; 1104 case 90: 1105 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1106 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1107 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1108 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1109 *(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2; 1110 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf); 1111 break; 1112 case 180: 1113 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1114 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1115 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1116 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1117 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2; 1118 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf); 1119 break; 1120 case 270: 1121 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr); 1122 *(ptr++) = (Sint16) SDL_SwapBE16(swapl); 1123 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr); 1124 *(ptr++) = (Sint16) SDL_SwapBE16(swapr); 1125 *(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2; 1126 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf); 1127 break; 1128 } 1129 } 1130 } 1131 1132 static void init_position_args(position_args *args) 1133 { 1134 memset(args, '\0', sizeof (position_args)); 1135 args->in_use = 0; 1136 args->room_angle = 0; 1137 args->left_u8 = args->right_u8 = args->distance_u8 = 255; 1138 args->left_f = args->right_f = args->distance_f = 1.0f; 1139 args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255; 1140 args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f; 1141 Mix_QuerySpec(NULL, NULL, (int *) &args->channels); 1142 } 1143 1144 1145 static position_args *get_position_arg(int channel) 1146 { 1147 void *rc; 1148 int i; 1149 1150 if (channel < 0) { 1151 if (pos_args_global == NULL) { 1152 pos_args_global = SDL_malloc(sizeof (position_args)); 1153 if (pos_args_global == NULL) { 1154 Mix_SetError("Out of memory"); 1155 return(NULL); 1156 } 1157 init_position_args(pos_args_global); 1158 } 1159 1160 return(pos_args_global); 1161 } 1162 1163 if (channel >= position_channels) { 1164 rc = SDL_realloc(pos_args_array, (channel + 1) * sizeof (position_args *)); 1165 if (rc == NULL) { 1166 Mix_SetError("Out of memory"); 1167 return(NULL); 1168 } 1169 pos_args_array = (position_args **) rc; 1170 for (i = position_channels; i <= channel; i++) { 1171 pos_args_array[i] = NULL; 1172 } 1173 position_channels = channel + 1; 1174 } 1175 1176 if (pos_args_array[channel] == NULL) { 1177 pos_args_array[channel] = (position_args *)SDL_malloc(sizeof(position_args)); 1178 if (pos_args_array[channel] == NULL) { 1179 Mix_SetError("Out of memory"); 1180 return(NULL); 1181 } 1182 init_position_args(pos_args_array[channel]); 1183 } 1184 1185 return(pos_args_array[channel]); 1186 } 1187 1188 1189 static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels) 1190 { 1191 Mix_EffectFunc_t f = NULL; 1192 1193 switch (format) { 1194 case AUDIO_U8: 1195 switch (channels) { 1196 case 1: 1197 case 2: 1198 f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 : 1199 _Eff_position_u8; 1200 break; 1201 case 4: 1202 f = _Eff_position_u8_c4; 1203 break; 1204 case 6: 1205 f = _Eff_position_u8_c6; 1206 break; 1207 } 1208 break; 1209 1210 case AUDIO_S8: 1211 switch (channels) { 1212 case 1: 1213 case 2: 1214 f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 : 1215 _Eff_position_s8; 1216 break; 1217 case 4: 1218 f = _Eff_position_s8_c4; 1219 break; 1220 case 6: 1221 f = _Eff_position_s8_c6; 1222 break; 1223 } 1224 break; 1225 1226 case AUDIO_U16LSB: 1227 switch (channels) { 1228 case 1: 1229 case 2: 1230 f = _Eff_position_u16lsb; 1231 break; 1232 case 4: 1233 f = _Eff_position_u16lsb_c4; 1234 break; 1235 case 6: 1236 f = _Eff_position_u16lsb_c6; 1237 break; 1238 } 1239 break; 1240 1241 case AUDIO_S16LSB: 1242 switch (channels) { 1243 case 1: 1244 case 2: 1245 f = _Eff_position_s16lsb; 1246 break; 1247 case 4: 1248 f = _Eff_position_s16lsb_c4; 1249 break; 1250 case 6: 1251 f = _Eff_position_s16lsb_c6; 1252 break; 1253 } 1254 break; 1255 1256 case AUDIO_U16MSB: 1257 switch (channels) { 1258 case 1: 1259 case 2: 1260 f = _Eff_position_u16msb; 1261 break; 1262 case 4: 1263 f = _Eff_position_u16msb_c4; 1264 break; 1265 case 6: 1266 f = _Eff_position_u16msb_c6; 1267 break; 1268 } 1269 break; 1270 1271 case AUDIO_S16MSB: 1272 switch (channels) { 1273 case 1: 1274 case 2: 1275 f = _Eff_position_s16msb; 1276 break; 1277 case 4: 1278 f = _Eff_position_s16msb_c4; 1279 break; 1280 case 6: 1281 f = _Eff_position_s16msb_c6; 1282 break; 1283 } 1284 break; 1285 1286 default: 1287 Mix_SetError("Unsupported audio format"); 1288 } 1289 1290 return(f); 1291 } 1292 1293 static Uint8 speaker_amplitude[6]; 1294 1295 static void set_amplitudes(int channels, int angle, int room_angle) 1296 { 1297 int left = 255, right = 255; 1298 int left_rear = 255, right_rear = 255, center = 255; 1299 1300 angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */ 1301 1302 if (channels == 2) 1303 { 1304 /* 1305 * We only attenuate by position if the angle falls on the far side 1306 * of center; That is, an angle that's due north would not attenuate 1307 * either channel. Due west attenuates the right channel to 0.0, and 1308 * due east attenuates the left channel to 0.0. Slightly east of 1309 * center attenuates the left channel a little, and the right channel 1310 * not at all. I think of this as occlusion by one's own head. :) 1311 * 1312 * ...so, we split our angle circle into four quadrants... 1313 */ 1314 if (angle < 90) { 1315 left = 255 - ((int) (255.0f * (((float) angle) / 89.0f))); 1316 } else if (angle < 180) { 1317 left = (int) (255.0f * (((float) (angle - 90)) / 89.0f)); 1318 } else if (angle < 270) { 1319 right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f))); 1320 } else { 1321 right = (int) (255.0f * (((float) (angle - 270)) / 89.0f)); 1322 } 1323 } 1324 1325 if (channels == 4 || channels == 6) 1326 { 1327 /* 1328 * An angle that's due north does not attenuate the center channel. 1329 * An angle in the first quadrant, 0-90, does not attenuate the RF. 1330 * 1331 * ...so, we split our angle circle into 8 ... 1332 * 1333 * CE 1334 * 0 1335 * LF | RF 1336 * | 1337 * 270<-------|----------->90 1338 * | 1339 * LR | RR 1340 * 180 1341 * 1342 */ 1343 if (angle < 45) { 1344 left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f))); 1345 left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f))); 1346 right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f))); 1347 } else if (angle < 90) { 1348 center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f))); 1349 left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f))); 1350 left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f))); 1351 right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f))); 1352 } else if (angle < 135) { 1353 center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f))); 1354 left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f))); 1355 right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f))); 1356 left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f))); 1357 } else if (angle < 180) { 1358 center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f))); 1359 left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f))); 1360 right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f))); 1361 left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f))); 1362 } else if (angle < 225) { 1363 center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f))); 1364 left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f))); 1365 right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f))); 1366 right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f))); 1367 } else if (angle < 270) { 1368 center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f))); 1369 left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f))); 1370 right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f))); 1371 right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f))); 1372 } else if (angle < 315) { 1373 center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f))); 1374 right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f))); 1375 left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f))); 1376 right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f))); 1377 } else { 1378 right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f))); 1379 left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f))); 1380 right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f))); 1381 } 1382 } 1383 1384 if (left < 0) left = 0; if (left > 255) left = 255; 1385 if (right < 0) right = 0; if (right > 255) right = 255; 1386 if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255; 1387 if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255; 1388 if (center < 0) center = 0; if (center > 255) center = 255; 1389 1390 if (room_angle == 90) { 1391 speaker_amplitude[0] = (Uint8)left_rear; 1392 speaker_amplitude[1] = (Uint8)left; 1393 speaker_amplitude[2] = (Uint8)right_rear; 1394 speaker_amplitude[3] = (Uint8)right; 1395 } 1396 else if (room_angle == 180) { 1397 if (channels == 2) { 1398 speaker_amplitude[0] = (Uint8)right; 1399 speaker_amplitude[1] = (Uint8)left; 1400 } 1401 else { 1402 speaker_amplitude[0] = (Uint8)right_rear; 1403 speaker_amplitude[1] = (Uint8)left_rear; 1404 speaker_amplitude[2] = (Uint8)right; 1405 speaker_amplitude[3] = (Uint8)left; 1406 } 1407 } 1408 else if (room_angle == 270) { 1409 speaker_amplitude[0] = (Uint8)right; 1410 speaker_amplitude[1] = (Uint8)right_rear; 1411 speaker_amplitude[2] = (Uint8)left; 1412 speaker_amplitude[3] = (Uint8)left_rear; 1413 } 1414 else { 1415 speaker_amplitude[0] = (Uint8)left; 1416 speaker_amplitude[1] = (Uint8)right; 1417 speaker_amplitude[2] = (Uint8)left_rear; 1418 speaker_amplitude[3] = (Uint8)right_rear; 1419 } 1420 speaker_amplitude[4] = (Uint8)center; 1421 speaker_amplitude[5] = 255; 1422 } 1423 1424 int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance); 1425 1426 int Mix_SetPanning(int channel, Uint8 left, Uint8 right) 1427 { 1428 Mix_EffectFunc_t f = NULL; 1429 int channels; 1430 Uint16 format; 1431 position_args *args = NULL; 1432 int retval = 1; 1433 1434 Mix_QuerySpec(NULL, &format, &channels); 1435 1436 if (channels != 2 && channels != 4 && channels != 6) /* it's a no-op; we call that successful. */ 1437 return(1); 1438 1439 if (channels > 2) { 1440 /* left = right = 255 => angle = 0, to unregister effect as when channels = 2 */ 1441 /* left = 255 => angle = -90; left = 0 => angle = +89 */ 1442 int angle = 0; 1443 if ((left != 255) || (right != 255)) { 1444 angle = (int)left; 1445 angle = 127 - angle; 1446 angle = -angle; 1447 angle = angle * 90 / 128; /* Make it larger for more effect? */ 1448 } 1449 return( Mix_SetPosition(channel, angle, 0) ); 1450 } 1451 1452 f = get_position_effect_func(format, channels); 1453 if (f == NULL) 1454 return(0); 1455 1456 SDL_LockAudio(); 1457 args = get_position_arg(channel); 1458 if (!args) { 1459 SDL_UnlockAudio(); 1460 return(0); 1461 } 1462 1463 /* it's a no-op; unregister the effect, if it's registered. */ 1464 if ((args->distance_u8 == 255) && (left == 255) && (right == 255)) { 1465 if (args->in_use) { 1466 retval = _Mix_UnregisterEffect_locked(channel, f); 1467 SDL_UnlockAudio(); 1468 return(retval); 1469 } else { 1470 SDL_UnlockAudio(); 1471 return(1); 1472 } 1473 } 1474 1475 args->left_u8 = left; 1476 args->left_f = ((float) left) / 255.0f; 1477 args->right_u8 = right; 1478 args->right_f = ((float) right) / 255.0f; 1479 args->room_angle = 0; 1480 1481 if (!args->in_use) { 1482 args->in_use = 1; 1483 retval=_Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void*)args); 1484 } 1485 1486 SDL_UnlockAudio(); 1487 return(retval); 1488 } 1489 1490 1491 int Mix_SetDistance(int channel, Uint8 distance) 1492 { 1493 Mix_EffectFunc_t f = NULL; 1494 Uint16 format; 1495 position_args *args = NULL; 1496 int channels; 1497 int retval = 1; 1498 1499 Mix_QuerySpec(NULL, &format, &channels); 1500 f = get_position_effect_func(format, channels); 1501 if (f == NULL) 1502 return(0); 1503 1504 SDL_LockAudio(); 1505 args = get_position_arg(channel); 1506 if (!args) { 1507 SDL_UnlockAudio(); 1508 return(0); 1509 } 1510 1511 distance = 255 - distance; /* flip it to our scale. */ 1512 1513 /* it's a no-op; unregister the effect, if it's registered. */ 1514 if ((distance == 255) && (args->left_u8 == 255) && (args->right_u8 == 255)) { 1515 if (args->in_use) { 1516 retval = _Mix_UnregisterEffect_locked(channel, f); 1517 SDL_UnlockAudio(); 1518 return(retval); 1519 } else { 1520 SDL_UnlockAudio(); 1521 return(1); 1522 } 1523 } 1524 1525 args->distance_u8 = distance; 1526 args->distance_f = ((float) distance) / 255.0f; 1527 if (!args->in_use) { 1528 args->in_use = 1; 1529 retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args); 1530 } 1531 1532 SDL_UnlockAudio(); 1533 return(retval); 1534 } 1535 1536 1537 int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance) 1538 { 1539 Mix_EffectFunc_t f = NULL; 1540 Uint16 format; 1541 int channels; 1542 position_args *args = NULL; 1543 Sint16 room_angle = 0; 1544 int retval = 1; 1545 1546 Mix_QuerySpec(NULL, &format, &channels); 1547 f = get_position_effect_func(format, channels); 1548 if (f == NULL) 1549 return(0); 1550 1551 angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */ 1552 1553 SDL_LockAudio(); 1554 args = get_position_arg(channel); 1555 if (!args) { 1556 SDL_UnlockAudio(); 1557 return(0); 1558 } 1559 1560 /* it's a no-op; unregister the effect, if it's registered. */ 1561 if ((!distance) && (!angle)) { 1562 if (args->in_use) { 1563 retval = _Mix_UnregisterEffect_locked(channel, f); 1564 SDL_UnlockAudio(); 1565 return(retval); 1566 } else { 1567 SDL_UnlockAudio(); 1568 return(1); 1569 } 1570 } 1571 1572 if (channels == 2) 1573 { 1574 if (angle > 180) 1575 room_angle = 180; /* exchange left and right channels */ 1576 else room_angle = 0; 1577 } 1578 1579 if (channels == 4 || channels == 6) 1580 { 1581 if (angle > 315) room_angle = 0; 1582 else if (angle > 225) room_angle = 270; 1583 else if (angle > 135) room_angle = 180; 1584 else if (angle > 45) room_angle = 90; 1585 else room_angle = 0; 1586 } 1587 1588 1589 distance = 255 - distance; /* flip it to scale Mix_SetDistance() uses. */ 1590 1591 set_amplitudes(channels, angle, room_angle); 1592 1593 args->left_u8 = speaker_amplitude[0]; 1594 args->left_f = ((float) speaker_amplitude[0]) / 255.0f; 1595 args->right_u8 = speaker_amplitude[1]; 1596 args->right_f = ((float) speaker_amplitude[1]) / 255.0f; 1597 args->left_rear_u8 = speaker_amplitude[2]; 1598 args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f; 1599 args->right_rear_u8 = speaker_amplitude[3]; 1600 args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f; 1601 args->center_u8 = speaker_amplitude[4]; 1602 args->center_f = ((float) speaker_amplitude[4]) / 255.0f; 1603 args->lfe_u8 = speaker_amplitude[5]; 1604 args->lfe_f = ((float) speaker_amplitude[5]) / 255.0f; 1605 args->distance_u8 = distance; 1606 args->distance_f = ((float) distance) / 255.0f; 1607 args->room_angle = room_angle; 1608 if (!args->in_use) { 1609 args->in_use = 1; 1610 retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args); 1611 } 1612 1613 SDL_UnlockAudio(); 1614 return(retval); 1615 } 1616 1617 1618 /* end of effects_position.c ... */ 1619 1620