142
static ALfloat aluLUTpos2Angle(ALint pos)
144
if(pos < QUADRANT_NUM)
145
return aluAtan((ALfloat)pos / (ALfloat)(QUADRANT_NUM - pos));
146
if(pos < 2 * QUADRANT_NUM)
147
return F_PI_2 + aluAtan((ALfloat)(pos - QUADRANT_NUM) / (ALfloat)(2 * QUADRANT_NUM - pos));
148
if(pos < 3 * QUADRANT_NUM)
149
return aluAtan((ALfloat)(pos - 2 * QUADRANT_NUM) / (ALfloat)(3 * QUADRANT_NUM - pos)) - F_PI;
150
return aluAtan((ALfloat)(pos - 3 * QUADRANT_NUM) / (ALfloat)(4 * QUADRANT_NUM - pos)) - F_PI_2;
153
ALint aluCart2LUTpos(ALfloat re, ALfloat im)
156
ALfloat denom = aluFabs(re) + aluFabs(im);
158
pos = (ALint)(QUADRANT_NUM*aluFabs(im) / denom + 0.5);
161
pos = 2 * QUADRANT_NUM - pos;
146
* Sets channel gains based on a given source's angle and its half-width. The
147
* angle and hwidth parameters are in radians.
149
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains)
151
ALfloat tmpgains[MaxChannels] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
152
enum Channel Speaker2Chan[MaxChannels];
153
ALfloat SpeakerAngle[MaxChannels];
154
ALfloat langle, rangle;
158
for(i = 0;i < device->NumChan;i++)
159
Speaker2Chan[i] = device->Speaker2Chan[i];
160
for(i = 0;i < device->NumChan;i++)
161
SpeakerAngle[i] = device->SpeakerAngle[i];
163
/* Some easy special-cases first... */
164
if(device->NumChan == 1 || hwidth >= F_PI)
166
/* Full coverage for all speakers. */
167
for(i = 0;i < device->NumChan;i++)
169
enum Channel chan = Speaker2Chan[i];
170
gains[chan] = ingain;
176
/* Infinitely small sound point. */
177
for(i = 0;i < device->NumChan-1;i++)
179
if(angle >= SpeakerAngle[i] && angle < SpeakerAngle[i+1])
181
/* Sound is between speakers i and i+1 */
182
a = (angle-SpeakerAngle[i]) /
183
(SpeakerAngle[i+1]-SpeakerAngle[i]);
184
gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain;
185
gains[Speaker2Chan[i+1]] = sqrtf( a) * ingain;
189
/* Sound is between last and first speakers */
190
if(angle < SpeakerAngle[0])
192
a = (angle-SpeakerAngle[i]) /
193
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
194
gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain;
195
gains[Speaker2Chan[0]] = sqrtf( a) * ingain;
199
if(fabsf(angle)+hwidth > F_PI)
201
/* The coverage area would go outside of -pi...+pi. Instead, rotate the
202
* speaker angles so it would be as if angle=0, and keep them wrapped
203
* within -pi...+pi. */
208
while(i < device->NumChan && device->SpeakerAngle[i]-angle < -F_PI)
210
for(done = 0;i < device->NumChan;done++)
212
SpeakerAngle[done] = device->SpeakerAngle[i]-angle;
213
Speaker2Chan[done] = device->Speaker2Chan[i];
216
for(i = 0;done < device->NumChan;i++)
218
SpeakerAngle[done] = device->SpeakerAngle[i]-angle + F_PI*2.0f;
219
Speaker2Chan[done] = device->Speaker2Chan[i];
225
/* NOTE: '< device->NumChan' on the iterators is correct here since
226
* we need to handle index 0. Because the iterators are unsigned,
227
* they'll underflow and wrap to become 0xFFFFFFFF, which will
228
* break as expected. */
229
ALuint done = device->NumChan-1;
230
ALuint i = device->NumChan-1;
231
while(i < device->NumChan && device->SpeakerAngle[i]-angle > F_PI)
233
for(done = device->NumChan-1;i < device->NumChan;done--)
235
SpeakerAngle[done] = device->SpeakerAngle[i]-angle;
236
Speaker2Chan[done] = device->Speaker2Chan[i];
239
for(i = device->NumChan-1;done < device->NumChan;i--)
241
SpeakerAngle[done] = device->SpeakerAngle[i]-angle - F_PI*2.0f;
242
Speaker2Chan[done] = device->Speaker2Chan[i];
248
langle = angle - hwidth;
249
rangle = angle + hwidth;
254
ALuint last = device->NumChan-1;
255
enum Channel chan = Speaker2Chan[i];
257
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
259
tmpgains[chan] = 1.0f;
263
if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle)
265
a = (langle-SpeakerAngle[i]) /
266
(SpeakerAngle[i+1]-SpeakerAngle[i]);
267
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
269
if(SpeakerAngle[i] > rangle)
271
a = (F_PI*2.0f + rangle-SpeakerAngle[last]) /
272
(F_PI*2.0f + SpeakerAngle[i]-SpeakerAngle[last]);
273
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
275
else if(SpeakerAngle[last] < rangle)
277
a = (rangle-SpeakerAngle[last]) /
278
(F_PI*2.0f + SpeakerAngle[i]-SpeakerAngle[last]);
279
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
283
for(i = 1;i < device->NumChan-1;i++)
285
enum Channel chan = Speaker2Chan[i];
286
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
288
tmpgains[chan] = 1.0f;
292
if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle)
294
a = (langle-SpeakerAngle[i]) /
295
(SpeakerAngle[i+1]-SpeakerAngle[i]);
296
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
298
if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle)
300
a = (rangle-SpeakerAngle[i-1]) /
301
(SpeakerAngle[i]-SpeakerAngle[i-1]);
302
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
307
i = device->NumChan-1;
309
enum Channel chan = Speaker2Chan[i];
310
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
312
tmpgains[Speaker2Chan[i]] = 1.0f;
315
if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle)
317
a = (rangle-SpeakerAngle[i-1]) /
318
(SpeakerAngle[i]-SpeakerAngle[i-1]);
319
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
321
if(SpeakerAngle[i] < langle)
323
a = (langle-SpeakerAngle[i]) /
324
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
325
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
327
else if(SpeakerAngle[0] > langle)
329
a = (F_PI*2.0f + langle-SpeakerAngle[i]) /
330
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
331
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
335
for(i = 0;i < device->NumChan;i++)
337
enum Channel chan = device->Speaker2Chan[i];
338
gains[chan] = sqrtf(tmpgains[chan]) * ingain;
167
343
ALvoid aluInitPanning(ALCdevice *Device)
169
ALfloat SpeakerAngle[MAXCHANNELS];
170
345
const char *layoutname = NULL;
171
346
enum Channel *Speaker2Chan;
172
ALfloat Alpha, Theta;
347
ALfloat *SpeakerAngle;
176
349
Speaker2Chan = Device->Speaker2Chan;
350
SpeakerAngle = Device->SpeakerAngle;
177
351
switch(Device->FmtChans)
180
354
Device->NumChan = 1;
181
Speaker2Chan[0] = FRONT_CENTER;
355
Speaker2Chan[0] = FrontCenter;
182
356
SpeakerAngle[0] = F_PI/180.0f * 0.0f;
183
357
layoutname = NULL;
186
360
case DevFmtStereo:
187
361
Device->NumChan = 2;
188
Speaker2Chan[0] = FRONT_LEFT;
189
Speaker2Chan[1] = FRONT_RIGHT;
362
Speaker2Chan[0] = FrontLeft;
363
Speaker2Chan[1] = FrontRight;
190
364
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
191
365
SpeakerAngle[1] = F_PI/180.0f * 90.0f;
192
366
layoutname = "layout_stereo";