48 next = confkey = layout_str;
52 next = strchr(confkey,
',');
58 }
while(isspace(*next) || *next ==
',');
61 sep = strchr(confkey,
'=');
62 if(!sep || confkey == sep)
64 ERR(
"Malformed speaker key: %s\n", confkey);
69 while(isspace(*end) && end != confkey)
73 if(strcmp(confkey,
"fl") == 0 || strcmp(confkey,
"front-left") == 0)
75 else if(strcmp(confkey,
"fr") == 0 || strcmp(confkey,
"front-right") == 0)
77 else if(strcmp(confkey,
"fc") == 0 || strcmp(confkey,
"front-center") == 0)
79 else if(strcmp(confkey,
"bl") == 0 || strcmp(confkey,
"back-left") == 0)
81 else if(strcmp(confkey,
"br") == 0 || strcmp(confkey,
"back-right") == 0)
83 else if(strcmp(confkey,
"bc") == 0 || strcmp(confkey,
"back-center") == 0)
85 else if(strcmp(confkey,
"sl") == 0 || strcmp(confkey,
"side-left") == 0)
87 else if(strcmp(confkey,
"sr") == 0 || strcmp(confkey,
"side-right") == 0)
91 ERR(
"Unknown speaker for %s: \"%s\"\n", name, confkey);
99 for(i = 0;i < chans;i++)
101 if(Speaker2Chan[i] == val)
104 if(angle >= -180 && angle <= 180)
105 SpeakerAngle[
i] = angle *
F_PI/180.0f;
107 ERR(
"Invalid angle for speaker \"%s\": %ld\n", confkey, angle);
115 for(i = 0;i < chans;i++)
120 for(i2 = i+1;i2 < chans;i2++)
122 if(SpeakerAngle[i2] < SpeakerAngle[min])
131 tmpf = SpeakerAngle[
i];
132 SpeakerAngle[
i] = SpeakerAngle[
min];
133 SpeakerAngle[
min] = tmpf;
135 tmpc = Speaker2Chan[
i];
136 Speaker2Chan[
i] = Speaker2Chan[
min];
137 Speaker2Chan[
min] = tmpc;
158 for(i = 0;i < device->
NumChan;i++)
160 for(i = 0;i < device->NumChan;i++)
167 for(i = 0;i < device->
NumChan;i++)
169 enum Channel chan = Speaker2Chan[
i];
170 gains[chan] = ingain;
177 for(i = 0;i < device->
NumChan-1;i++)
179 if(angle >= SpeakerAngle[i] && angle < SpeakerAngle[i+1])
182 a = (angle-SpeakerAngle[
i]) /
183 (SpeakerAngle[i+1]-SpeakerAngle[i]);
184 gains[Speaker2Chan[
i]] = sqrtf(1.0
f-a) * ingain;
185 gains[Speaker2Chan[i+1]] = sqrtf( a) * ingain;
190 if(angle < SpeakerAngle[0])
192 a = (angle-SpeakerAngle[
i]) /
193 (
F_PI*2.0
f + SpeakerAngle[0]-SpeakerAngle[i]);
194 gains[Speaker2Chan[
i]] = sqrtf(1.0
f-a) * ingain;
195 gains[Speaker2Chan[0]] = sqrtf( a) * ingain;
199 if(fabsf(angle)+hwidth >
F_PI)
210 for(done = 0;i < device->
NumChan;done++)
216 for(i = 0;done < device->
NumChan;i++)
233 for(done = device->
NumChan-1;i < device->NumChan;done--)
239 for(i = device->
NumChan-1;done < device->NumChan;i--)
248 langle = angle - hwidth;
249 rangle = angle + hwidth;
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.0
f, 1.0
f-a);
269 if(SpeakerAngle[i] > rangle)
271 a = (
F_PI*2.0f + rangle-SpeakerAngle[last]) /
272 (
F_PI*2.0
f + SpeakerAngle[i]-SpeakerAngle[last]);
273 tmpgains[chan] =
lerp(tmpgains[chan], 1.0
f, a);
275 else if(SpeakerAngle[last] < rangle)
277 a = (rangle-SpeakerAngle[last]) /
278 (
F_PI*2.0
f + SpeakerAngle[i]-SpeakerAngle[last]);
279 tmpgains[chan] =
lerp(tmpgains[chan], 1.0
f, 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.0
f, 1.0
f-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.0
f, a);
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.0
f, a);
321 if(SpeakerAngle[i] < langle)
323 a = (langle-SpeakerAngle[
i]) /
324 (
F_PI*2.0
f + SpeakerAngle[0]-SpeakerAngle[i]);
325 tmpgains[chan] =
lerp(tmpgains[chan], 1.0
f, 1.0
f-a);
327 else if(SpeakerAngle[0] > langle)
329 a = (
F_PI*2.0f + langle-SpeakerAngle[
i]) /
330 (
F_PI*2.0
f + SpeakerAngle[0]-SpeakerAngle[i]);
331 tmpgains[chan] =
lerp(tmpgains[chan], 1.0
f, 1.0
f-a);
335 for(i = 0;i < device->
NumChan;i++)
338 gains[chan] = sqrtf(tmpgains[chan]) * ingain;
345 const char *layoutname =
NULL;
356 SpeakerAngle[0] =
F_PI/180.0f * 0.0f;
364 SpeakerAngle[0] =
F_PI/180.0f * -90.0f;
365 SpeakerAngle[1] =
F_PI/180.0f * 90.0f;
366 layoutname =
"layout_stereo";
375 SpeakerAngle[0] =
F_PI/180.0f * -135.0f;
376 SpeakerAngle[1] =
F_PI/180.0f * -45.0f;
377 SpeakerAngle[2] =
F_PI/180.0f * 45.0f;
378 SpeakerAngle[3] =
F_PI/180.0f * 135.0f;
379 layoutname =
"layout_quad";
389 SpeakerAngle[0] =
F_PI/180.0f * -110.0f;
390 SpeakerAngle[1] =
F_PI/180.0f * -30.0f;
391 SpeakerAngle[2] =
F_PI/180.0f * 0.0f;
392 SpeakerAngle[3] =
F_PI/180.0f * 30.0f;
393 SpeakerAngle[4] =
F_PI/180.0f * 110.0f;
394 layoutname =
"layout_surround51";
404 SpeakerAngle[0] =
F_PI/180.0f * -90.0f;
405 SpeakerAngle[1] =
F_PI/180.0f * -30.0f;
406 SpeakerAngle[2] =
F_PI/180.0f * 0.0f;
407 SpeakerAngle[3] =
F_PI/180.0f * 30.0f;
408 SpeakerAngle[4] =
F_PI/180.0f * 90.0f;
409 layoutname =
"layout_side51";
420 SpeakerAngle[0] =
F_PI/180.0f * -90.0f;
421 SpeakerAngle[1] =
F_PI/180.0f * -30.0f;
422 SpeakerAngle[2] =
F_PI/180.0f * 0.0f;
423 SpeakerAngle[3] =
F_PI/180.0f * 30.0f;
424 SpeakerAngle[4] =
F_PI/180.0f * 90.0f;
425 SpeakerAngle[5] =
F_PI/180.0f * 180.0f;
426 layoutname =
"layout_surround61";
438 SpeakerAngle[0] =
F_PI/180.0f * -150.0f;
439 SpeakerAngle[1] =
F_PI/180.0f * -90.0f;
440 SpeakerAngle[2] =
F_PI/180.0f * -30.0f;
441 SpeakerAngle[3] =
F_PI/180.0f * 0.0f;
442 SpeakerAngle[4] =
F_PI/180.0f * 30.0f;
443 SpeakerAngle[5] =
F_PI/180.0f * 90.0f;
444 SpeakerAngle[6] =
F_PI/180.0f * 150.0f;
445 layoutname =
"layout_surround71";
int ConfigValueStr(const char *blockName, const char *keyName, const char **ret)
GLuint const GLfloat * val
static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MaxChannels], enum Channel Speaker2Chan[MaxChannels], ALint chans)
char * strdup(const char *inStr)
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
GLboolean GLboolean GLboolean GLboolean a
EGLImageKHR EGLint * name
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint i2
ALfloat SpeakerAngle[MaxChannels]
enum Channel Speaker2Chan[MaxChannels]
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains)
enum DevFmtChannels FmtChans
ALvoid aluInitPanning(ALCdevice *Device)