Store the panning LUT in the device
This commit is contained in:
parent
49201e892b
commit
aace50ebf4
101
Alc/ALc.c
101
Alc/ALc.c
@ -507,103 +507,6 @@ void EnableRTPrio(ALint level)
|
||||
AL_PRINT("Failed to set priority level for thread\n");
|
||||
}
|
||||
|
||||
static void SetupChannelMatrix(ALCdevice *Device)
|
||||
{
|
||||
ALfloat maxout;
|
||||
ALuint s, s2;
|
||||
|
||||
for(s = 0;s < OUTPUTCHANNELS;s++)
|
||||
{
|
||||
for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
|
||||
Device->ChannelMatrix[s][s2] = ((s==s2) ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
switch(Device->Format)
|
||||
{
|
||||
case AL_FORMAT_MONO8:
|
||||
case AL_FORMAT_MONO16:
|
||||
case AL_FORMAT_MONO_FLOAT32:
|
||||
Device->ChannelMatrix[FRONT_LEFT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[FRONT_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_LEFT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][FRONT_CENTER] = 1.0f;
|
||||
break;
|
||||
|
||||
case AL_FORMAT_STEREO8:
|
||||
case AL_FORMAT_STEREO16:
|
||||
case AL_FORMAT_STEREO_FLOAT32:
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = 1.0f;
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = 1.0f;
|
||||
Device->ChannelMatrix[BACK_LEFT][FRONT_LEFT] = 1.0f;
|
||||
Device->ChannelMatrix[BACK_RIGHT][FRONT_RIGHT] = 1.0f;
|
||||
Device->ChannelMatrix[BACK_CENTER][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_QUAD8:
|
||||
case AL_FORMAT_QUAD16:
|
||||
case AL_FORMAT_QUAD32:
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_51CHN8:
|
||||
case AL_FORMAT_51CHN16:
|
||||
case AL_FORMAT_51CHN32:
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_61CHN8:
|
||||
case AL_FORMAT_61CHN16:
|
||||
case AL_FORMAT_61CHN32:
|
||||
Device->ChannelMatrix[BACK_LEFT][BACK_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_LEFT][SIDE_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_RIGHT][BACK_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_RIGHT][SIDE_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_71CHN8:
|
||||
case AL_FORMAT_71CHN16:
|
||||
case AL_FORMAT_71CHN32:
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for(s = 0;s < OUTPUTCHANNELS;s++)
|
||||
{
|
||||
ALfloat out = 0.0f;
|
||||
for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
|
||||
out += Device->ChannelMatrix[s2][s];
|
||||
maxout = __max(maxout, out);
|
||||
}
|
||||
|
||||
maxout = 1.0f/maxout;
|
||||
for(s = 0;s < OUTPUTCHANNELS;s++)
|
||||
{
|
||||
for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
|
||||
Device->ChannelMatrix[s2][s] *= maxout;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
IsDevice
|
||||
@ -1380,7 +1283,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
|
||||
ProcessContext(NULL);
|
||||
return NULL;
|
||||
}
|
||||
SetupChannelMatrix(device);
|
||||
aluInitPanning(device);
|
||||
|
||||
for(i = 0;i < device->NumContexts;i++)
|
||||
{
|
||||
@ -1420,7 +1323,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
|
||||
}
|
||||
source->NeedsUpdate = AL_TRUE;
|
||||
}
|
||||
aluInitPanning(context);
|
||||
ProcessContext(context);
|
||||
}
|
||||
|
||||
@ -1461,7 +1363,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
|
||||
ALContext->Device = device;
|
||||
|
||||
InitContext(ALContext);
|
||||
aluInitPanning(ALContext);
|
||||
|
||||
ALContext->next = g_pContextList;
|
||||
g_pContextList = ALContext;
|
||||
|
123
Alc/ALu.c
123
Alc/ALu.c
@ -226,14 +226,109 @@ static __inline ALfloat aluLUTpos2Angle(ALint pos)
|
||||
return aluAtan((ALfloat)(pos - 3 * QUADRANT_NUM) / (ALfloat)(4 * QUADRANT_NUM - pos)) - M_PI_2;
|
||||
}
|
||||
|
||||
ALvoid aluInitPanning(ALCcontext *Context)
|
||||
ALvoid aluInitPanning(ALCdevice *Device)
|
||||
{
|
||||
ALint pos, offset, s;
|
||||
ALfloat Alpha, Theta;
|
||||
ALfloat SpeakerAngle[OUTPUTCHANNELS];
|
||||
ALint Speaker2Chan[OUTPUTCHANNELS];
|
||||
ALfloat Alpha, Theta;
|
||||
ALint pos, offset;
|
||||
ALfloat maxout;
|
||||
ALuint s, s2;
|
||||
|
||||
Context->NumChan = 8;
|
||||
for(s = 0;s < OUTPUTCHANNELS;s++)
|
||||
{
|
||||
for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
|
||||
Device->ChannelMatrix[s][s2] = ((s==s2) ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
switch(Device->Format)
|
||||
{
|
||||
case AL_FORMAT_MONO8:
|
||||
case AL_FORMAT_MONO16:
|
||||
case AL_FORMAT_MONO_FLOAT32:
|
||||
Device->ChannelMatrix[FRONT_LEFT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[FRONT_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_LEFT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][FRONT_CENTER] = 1.0f;
|
||||
break;
|
||||
|
||||
case AL_FORMAT_STEREO8:
|
||||
case AL_FORMAT_STEREO16:
|
||||
case AL_FORMAT_STEREO_FLOAT32:
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = 1.0f;
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = 1.0f;
|
||||
Device->ChannelMatrix[BACK_LEFT][FRONT_LEFT] = 1.0f;
|
||||
Device->ChannelMatrix[BACK_RIGHT][FRONT_RIGHT] = 1.0f;
|
||||
Device->ChannelMatrix[BACK_CENTER][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_QUAD8:
|
||||
case AL_FORMAT_QUAD16:
|
||||
case AL_FORMAT_QUAD32:
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_51CHN8:
|
||||
case AL_FORMAT_51CHN16:
|
||||
case AL_FORMAT_51CHN32:
|
||||
Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_61CHN8:
|
||||
case AL_FORMAT_61CHN16:
|
||||
case AL_FORMAT_61CHN32:
|
||||
Device->ChannelMatrix[BACK_LEFT][BACK_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_LEFT][SIDE_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_RIGHT][BACK_CENTER] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_RIGHT][SIDE_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_71CHN8:
|
||||
case AL_FORMAT_71CHN16:
|
||||
case AL_FORMAT_71CHN32:
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
|
||||
Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
maxout = 1.0f;
|
||||
for(s = 0;s < OUTPUTCHANNELS;s++)
|
||||
{
|
||||
ALfloat out = 0.0f;
|
||||
for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
|
||||
out += Device->ChannelMatrix[s2][s];
|
||||
maxout = __max(maxout, out);
|
||||
}
|
||||
|
||||
maxout = 1.0f/maxout;
|
||||
for(s = 0;s < OUTPUTCHANNELS;s++)
|
||||
{
|
||||
for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
|
||||
Device->ChannelMatrix[s2][s] *= maxout;
|
||||
}
|
||||
|
||||
Device->NumChan = 8;
|
||||
Speaker2Chan[0] = BACK_LEFT;
|
||||
Speaker2Chan[1] = SIDE_LEFT;
|
||||
Speaker2Chan[2] = FRONT_LEFT;
|
||||
@ -250,40 +345,40 @@ ALvoid aluInitPanning(ALCcontext *Context)
|
||||
SpeakerAngle[5] = 90.0f * M_PI/180.0f;
|
||||
SpeakerAngle[6] = 150.0f * M_PI/180.0f;
|
||||
SpeakerAngle[7] = 180.0f * M_PI/180.0f;
|
||||
SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Context->NumChan);
|
||||
SetSpeakerArrangement("layout", SpeakerAngle, Speaker2Chan, Device->NumChan);
|
||||
|
||||
for(pos = 0; pos < LUT_NUM; pos++)
|
||||
{
|
||||
/* clear all values */
|
||||
offset = OUTPUTCHANNELS * pos;
|
||||
for(s = 0; s < OUTPUTCHANNELS; s++)
|
||||
Context->PanningLUT[offset+s] = 0.0f;
|
||||
Device->PanningLUT[offset+s] = 0.0f;
|
||||
|
||||
/* source angle */
|
||||
Theta = aluLUTpos2Angle(pos);
|
||||
|
||||
/* set panning values */
|
||||
for(s = 0; s < Context->NumChan - 1; s++)
|
||||
for(s = 0; s < Device->NumChan - 1; s++)
|
||||
{
|
||||
if(Theta >= SpeakerAngle[s] && Theta < SpeakerAngle[s+1])
|
||||
{
|
||||
/* source between speaker s and speaker s+1 */
|
||||
Alpha = M_PI_2 * (Theta-SpeakerAngle[s]) /
|
||||
(SpeakerAngle[s+1]-SpeakerAngle[s]);
|
||||
Context->PanningLUT[offset + Speaker2Chan[s]] = cos(Alpha);
|
||||
Context->PanningLUT[offset + Speaker2Chan[s+1]] = sin(Alpha);
|
||||
Device->PanningLUT[offset + Speaker2Chan[s]] = cos(Alpha);
|
||||
Device->PanningLUT[offset + Speaker2Chan[s+1]] = sin(Alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(s == Context->NumChan - 1)
|
||||
if(s == Device->NumChan - 1)
|
||||
{
|
||||
/* source between last and first speaker */
|
||||
if(Theta < SpeakerAngle[0])
|
||||
Theta += 2.0f * M_PI;
|
||||
Alpha = M_PI_2 * (Theta-SpeakerAngle[s]) /
|
||||
(2.0f * M_PI + SpeakerAngle[0]-SpeakerAngle[s]);
|
||||
Context->PanningLUT[offset + Speaker2Chan[s]] = cos(Alpha);
|
||||
Context->PanningLUT[offset + Speaker2Chan[0]] = sin(Alpha);
|
||||
Device->PanningLUT[offset + Speaker2Chan[s]] = cos(Alpha);
|
||||
Device->PanningLUT[offset + Speaker2Chan[0]] = sin(Alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -720,12 +815,12 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource)
|
||||
}
|
||||
|
||||
pos = aluCart2LUTpos(-Position[2], Position[0]);
|
||||
SpeakerGain = &ALContext->PanningLUT[OUTPUTCHANNELS * pos];
|
||||
SpeakerGain = &ALContext->Device->PanningLUT[OUTPUTCHANNELS * pos];
|
||||
|
||||
DirGain = aluSqrt(Position[0]*Position[0] + Position[2]*Position[2]);
|
||||
// elevation adjustment for directional gain. this sucks, but
|
||||
// has low complexity
|
||||
AmbientGain = 1.0/aluSqrt(ALContext->NumChan) * (1.0-DirGain);
|
||||
AmbientGain = 1.0/aluSqrt(ALContext->Device->NumChan) * (1.0-DirGain);
|
||||
for(s = 0; s < OUTPUTCHANNELS; s++)
|
||||
{
|
||||
ALfloat gain = SpeakerGain[s]*DirGain + AmbientGain;
|
||||
|
@ -1131,7 +1131,7 @@ static ALvoid EAXVerbUpdate(ALeffectState *effect, ALCcontext *Context, const AL
|
||||
|
||||
// Update early and late 3D panning.
|
||||
Update3DPanning(Effect->Reverb.ReflectionsPan, Effect->Reverb.LateReverbPan,
|
||||
Context->PanningLUT, State);
|
||||
Context->Device->PanningLUT, State);
|
||||
}
|
||||
|
||||
// This processes the reverb state, given the input samples and an output
|
||||
|
@ -279,6 +279,9 @@ struct ALCdevice_struct
|
||||
|
||||
ALfloat ChannelMatrix[OUTPUTCHANNELS][OUTPUTCHANNELS];
|
||||
|
||||
ALfloat PanningLUT[OUTPUTCHANNELS * LUT_NUM];
|
||||
ALuint NumChan;
|
||||
|
||||
// Contexts created on this device
|
||||
ALCcontext **Contexts;
|
||||
ALuint NumContexts;
|
||||
@ -324,9 +327,6 @@ struct ALCcontext_struct
|
||||
ALfloat DopplerVelocity;
|
||||
ALfloat flSpeedOfSound;
|
||||
|
||||
ALfloat PanningLUT[OUTPUTCHANNELS * LUT_NUM];
|
||||
ALint NumChan;
|
||||
|
||||
ALCdevice *Device;
|
||||
const ALCchar *ExtensionList;
|
||||
|
||||
|
@ -175,7 +175,7 @@ static __inline ALint aluCart2LUTpos(ALfloat re, ALfloat im)
|
||||
return pos%LUT_NUM;
|
||||
}
|
||||
|
||||
ALvoid aluInitPanning(ALCcontext *Context);
|
||||
ALvoid aluInitPanning(ALCdevice *Device);
|
||||
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
|
||||
ALvoid aluHandleDisconnect(ALCdevice *device);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user