effect_position.c
上传用户:nini_0081
上传日期:2022-07-21
资源大小:2628k
文件大小:60k
源码类别:

多媒体编程

开发平台:

DOS

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