diff options
author | Chris Robinson <[email protected]> | 2012-08-09 02:31:19 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2012-08-09 02:31:19 -0700 |
commit | 0dde7dd88a24a59a484ec36bc26bec19e0ee7d0a (patch) | |
tree | 3da0ffba34d5640112e5425e8de22f60da66fedf /Alc/panning.c | |
parent | 1323e11701984d93c34b7049929b1f1d3bc418bc (diff) |
Use a more efficient method to offset the speaker angles when computing gains
Diffstat (limited to 'Alc/panning.c')
-rw-r--r-- | Alc/panning.c | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/Alc/panning.c b/Alc/panning.c index 6b412f89..d8191d8d 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -201,43 +201,49 @@ ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, /* The coverage area would go outside of -pi...+pi. Instead, rotate the * speaker angles so it would be as if angle=0, and keep them wrapped * within -pi...+pi. */ - for(i = 0;i < device->NumChan;i++) + if(angle > 0.0f) { - SpeakerAngle[i] -= angle; - if(SpeakerAngle[i] > F_PI) - SpeakerAngle[i] -= F_PI*2.0f; - else if(SpeakerAngle[i] < -F_PI) - SpeakerAngle[i] += F_PI*2.0f; + ALuint done = 0; + ALuint i = 0; + while(i < device->NumChan && device->SpeakerAngle[i]-angle < -F_PI) + i++; + for(done = 0;i < device->NumChan;done++) + { + SpeakerAngle[done] = device->SpeakerAngle[i]-angle; + Speaker2Chan[done] = device->Speaker2Chan[i]; + i++; + } + for(i = 0;done < device->NumChan;i++) + { + SpeakerAngle[done] = device->SpeakerAngle[i]-angle + F_PI*2.0f; + Speaker2Chan[done] = device->Speaker2Chan[i]; + done++; + } } - angle = 0.0f; - - /* The speaker angles are expected to be in ascending order. There - * should be a better way to resort the lists... */ - for(i = 0;i < device->NumChan-1;i++) + else { - ALuint min = i; - ALuint j; - - for(j = i+1;j < device->NumChan;j++) + /* NOTE: '< device->NumChan' on the iterators is correct here since + * we need to handle index 0. Because the iterators are unsigned, + * they'll underflow and wrap to become 0xFFFFFFFF, which will + * break as expected. */ + ALuint done = device->NumChan-1; + ALuint i = device->NumChan-1; + while(i < device->NumChan && device->SpeakerAngle[i]-angle > F_PI) + i--; + for(done = device->NumChan-1;i < device->NumChan;done--) { - if(SpeakerAngle[j] < SpeakerAngle[min]) - min = j; + SpeakerAngle[done] = device->SpeakerAngle[i]-angle; + Speaker2Chan[done] = device->Speaker2Chan[i]; + i--; } - - if(min != i) + for(i = device->NumChan-1;done < device->NumChan;i--) { - ALfloat tmpf; - enum Channel tmpc; - - tmpf = SpeakerAngle[i]; - SpeakerAngle[i] = SpeakerAngle[min]; - SpeakerAngle[min] = tmpf; - - tmpc = Speaker2Chan[i]; - Speaker2Chan[i] = Speaker2Chan[min]; - Speaker2Chan[min] = tmpc; + SpeakerAngle[done] = device->SpeakerAngle[i]-angle - F_PI*2.0f; + Speaker2Chan[done] = device->Speaker2Chan[i]; + done--; } } + angle = 0.0f; } langle = angle - hwidth; rangle = angle + hwidth; |