I was investigating cracking sound and found this in effect_position.c
in Mix_SetPosition()
:
angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */
Documentation for Mix_SetPosition()
says:
(angle) will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
However if i pass angle -90, this becomes angle = SDL_abs(-90) % 360
, 90 % 360 is obviously 90, so channel position changes from (intended) left (-90) to the (unintended) right (90). Removing SDL_abs
doesn’t help either, -90 % 360 = -90, so it’s not between 0…360.
I think intention was to perform modulo operation on angle, so -90 % 360 = 270 - this makes sense and matches documentation, i changed this line to
angle = (angle % 360 + 360) % 360; /* make angle between 0 and 359. */
and this kinda works.
But it also might be that i’m doing something wrong with mixer. Am i missing anything or shall i report bug or send patch or something?
Regarding cracking sound: i think the problem is in this bit of Mix_SetPosition()
:
if (channels == 2)
{
if (angle > 180)
room_angle = 180; /* exchange left and right channels */
else room_angle = 0;
}
And then in set_amplitudes()
channels seemingly swapped as advertised, but i don’t quite understand how this works.
- Why channels are swapped if effect is behind observer? I thought that if effect is on the left from the observer, it will stay on the left regardless if it’s in front of behind, no?
-
set_amplitudes()
is adjusting something in static array:
static Uint8 speaker_amplitude[6];
But what if i have several effects playing at the same time, won’t setting this up for second (or third) effect discard settings for first effect?
Steps to reproduce my issue looks like this:
- Create effect directly in front of player
- Rotate player slightly to the right (5-10 degrees)
- Adjust effect position with
Mix_SetPosition()
(angle would be something like 360-7=353)
- Rotate player slightly to the left (10-20 degrees)
- Adjust effect position with
Mix_SetPosition()
(angle would be something like 0+7=7)
- Repeat steps 2-5
The point is to change angle to the opposite across zero while effect is still playing. When i do that, sound starts cracking. If i disable “exchange left and right channels” then effect is playing without cracking.
What am i doing wrong? Shouldn’t i call Mix_SetPosition()
or is there some specific place where it is appropriate to call this function to adjust effect for changed position relatively to observer? Or maybe my mixer settings incorrect?
Any ideas?