aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/ALu.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-01-25 19:20:47 -0800
committerChris Robinson <[email protected]>2009-01-25 19:20:47 -0800
commitf82c88f01693c3a70428b3ee4311345ffbbee7d9 (patch)
tree9d2c30065deea6673ddcb9beb6987f719a42db1f /Alc/ALu.c
parent98e86decadb3ed9b0e1dde6f417d19b9a286d826 (diff)
Add options for user-configurable speaker arrangements
Diffstat (limited to 'Alc/ALu.c')
-rw-r--r--Alc/ALu.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index da5122b4..e29cb025 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -25,6 +25,8 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
+
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
@@ -259,6 +261,87 @@ static __inline ALvoid aluMatrixVector(ALfloat *vector,ALfloat matrix[3][3])
memcpy(vector, result, sizeof(result));
}
+static ALvoid SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[OUTPUTCHANNELS],
+ ALint Speaker2Chan[OUTPUTCHANNELS], ALint chans)
+{
+ const char *confkey;
+ const char *next;
+ const char *sep;
+ const char *end;
+ int i, val;
+
+ confkey = GetConfigValue(NULL, name, "");
+ next = confkey;
+ while(next && *next)
+ {
+ confkey = next;
+ next = strchr(confkey, ',');
+ if(next)
+ {
+ do {
+ next++;
+ } while(isspace(*next));
+ }
+
+ sep = strchr(confkey, '=');
+ if(!sep || confkey == sep)
+ continue;
+
+ end = sep - 1;
+ while(isspace(*end) && end != confkey)
+ end--;
+
+ if(strncmp(confkey, "fl", end-confkey) == 0)
+ val = FRONT_LEFT;
+ else if(strncmp(confkey, "fr", end-confkey) == 0)
+ val = FRONT_RIGHT;
+ else if(strncmp(confkey, "fc", end-confkey) == 0)
+ val = FRONT_CENTER;
+ else if(strncmp(confkey, "bl", end-confkey) == 0)
+ val = BACK_LEFT;
+ else if(strncmp(confkey, "br", end-confkey) == 0)
+ val = BACK_RIGHT;
+ else if(strncmp(confkey, "bc", end-confkey) == 0)
+ val = BACK_CENTER;
+ else if(strncmp(confkey, "sl", end-confkey) == 0)
+ val = SIDE_LEFT;
+ else if(strncmp(confkey, "sr", end-confkey) == 0)
+ val = SIDE_RIGHT;
+ else
+ {
+ AL_PRINT("Unknown speaker for %s: \"%c%c\"\n", name, confkey[0], confkey[1]);
+ continue;
+ }
+
+ sep++;
+ while(isspace(*sep))
+ sep++;
+
+ for(i = 0;i < chans;i++)
+ {
+ if(Speaker2Chan[i] == val)
+ {
+ val = strtol(sep, NULL, 10);
+ if(val >= -180 && val <= 180)
+ SpeakerAngle[i] = val * M_PI/180.0f;
+ else
+ AL_PRINT("Invalid angle for speaker \"%c%c\": %d\n", confkey[0], confkey[1], val);
+ break;
+ }
+ }
+ }
+
+ for(i = 1;i < chans;i++)
+ {
+ if(SpeakerAngle[i] <= SpeakerAngle[i-1])
+ {
+ AL_PRINT("Speaker %d of %d does not follow previous: %f > %f\n", i, chans,
+ SpeakerAngle[i-1] * 180.0f/M_PI, SpeakerAngle[i] * 180.0f/M_PI);
+ SpeakerAngle[i] = SpeakerAngle[i-1] + 1 * 180.0f/M_PI;
+ }
+ }
+}
+
static __inline ALfloat aluLUTpos2Angle(ALint pos)
{
if(pos < QUADRANT_NUM)
@@ -291,6 +374,8 @@ ALvoid aluInitPanning(ALCcontext *Context)
Speaker2Chan[1] = FRONT_RIGHT;
SpeakerAngle[0] = -90.0f * M_PI/180.0f;
SpeakerAngle[1] = 90.0f * M_PI/180.0f;
+ SetSpeakerArrangement("layout_STEREO", SpeakerAngle, Speaker2Chan, Context->NumChan);
+ break;
case AL_FORMAT_QUAD8:
case AL_FORMAT_QUAD16:
@@ -304,6 +389,7 @@ ALvoid aluInitPanning(ALCcontext *Context)
SpeakerAngle[1] = -45.0f * M_PI/180.0f;
SpeakerAngle[2] = 45.0f * M_PI/180.0f;
SpeakerAngle[3] = 135.0f * M_PI/180.0f;
+ SetSpeakerArrangement("layout_QUAD", SpeakerAngle, Speaker2Chan, Context->NumChan);
break;
case AL_FORMAT_51CHN8:
@@ -320,6 +406,7 @@ ALvoid aluInitPanning(ALCcontext *Context)
SpeakerAngle[2] = 0.0f * M_PI/180.0f;
SpeakerAngle[3] = 30.0f * M_PI/180.0f;
SpeakerAngle[4] = 110.0f * M_PI/180.0f;
+ SetSpeakerArrangement("layout_51CHN", SpeakerAngle, Speaker2Chan, Context->NumChan);
break;
case AL_FORMAT_61CHN8:
@@ -338,6 +425,7 @@ ALvoid aluInitPanning(ALCcontext *Context)
SpeakerAngle[3] = 30.0f * M_PI/180.0f;
SpeakerAngle[4] = 90.0f * M_PI/180.0f;
SpeakerAngle[5] = 180.0f * M_PI/180.0f;
+ SetSpeakerArrangement("layout_61CHN", SpeakerAngle, Speaker2Chan, Context->NumChan);
break;
case AL_FORMAT_71CHN8:
@@ -358,6 +446,7 @@ ALvoid aluInitPanning(ALCcontext *Context)
SpeakerAngle[4] = 30.0f * M_PI/180.0f;
SpeakerAngle[5] = 90.0f * M_PI/180.0f;
SpeakerAngle[6] = 150.0f * M_PI/180.0f;
+ SetSpeakerArrangement("layout_71CHN", SpeakerAngle, Speaker2Chan, Context->NumChan);
break;
default: