Support B-Format source rotation with AL_ORIENTATION
This commit is contained in:
parent
336aba6f1f
commit
3d2853274d
43
Alc/ALu.c
43
Alc/ALu.c
@ -288,6 +288,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
|||||||
ALfloat WetGainHF[MAX_SENDS];
|
ALfloat WetGainHF[MAX_SENDS];
|
||||||
ALfloat WetGainLF[MAX_SENDS];
|
ALfloat WetGainLF[MAX_SENDS];
|
||||||
ALuint NumSends, Frequency;
|
ALuint NumSends, Frequency;
|
||||||
|
ALboolean Relative;
|
||||||
const struct ChanMap *chans = NULL;
|
const struct ChanMap *chans = NULL;
|
||||||
ALuint num_channels = 0;
|
ALuint num_channels = 0;
|
||||||
ALboolean DirectChannels;
|
ALboolean DirectChannels;
|
||||||
@ -307,6 +308,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
|||||||
MinVolume = ALSource->MinGain;
|
MinVolume = ALSource->MinGain;
|
||||||
MaxVolume = ALSource->MaxGain;
|
MaxVolume = ALSource->MaxGain;
|
||||||
Pitch = ALSource->Pitch;
|
Pitch = ALSource->Pitch;
|
||||||
|
Relative = ALSource->HeadRelative;
|
||||||
DirectChannels = ALSource->DirectChannels;
|
DirectChannels = ALSource->DirectChannels;
|
||||||
|
|
||||||
voice->Direct.OutBuffer = Device->DryBuffer;
|
voice->Direct.OutBuffer = Device->DryBuffer;
|
||||||
@ -414,12 +416,51 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
|
|||||||
|
|
||||||
if(isbformat)
|
if(isbformat)
|
||||||
{
|
{
|
||||||
|
ALfloat N[3], V[3], U[3];
|
||||||
|
ALfloat matrix[4][4];
|
||||||
|
|
||||||
|
/* AT then UP */
|
||||||
|
N[0] = ALSource->Orientation[0][0];
|
||||||
|
N[1] = ALSource->Orientation[0][1];
|
||||||
|
N[2] = ALSource->Orientation[0][2];
|
||||||
|
aluNormalize(N);
|
||||||
|
V[0] = ALSource->Orientation[1][0];
|
||||||
|
V[1] = ALSource->Orientation[1][1];
|
||||||
|
V[2] = ALSource->Orientation[1][2];
|
||||||
|
aluNormalize(V);
|
||||||
|
if(!Relative)
|
||||||
|
{
|
||||||
|
ALfloat (*restrict lmatrix)[4] = ALContext->Listener->Params.Matrix;
|
||||||
|
aluMatrixVector(N, 0.0f, lmatrix);
|
||||||
|
aluMatrixVector(V, 0.0f, lmatrix);
|
||||||
|
}
|
||||||
|
/* Build and normalize right-vector */
|
||||||
|
aluCrossproduct(N, V, U);
|
||||||
|
aluNormalize(U);
|
||||||
|
|
||||||
|
matrix[0][0] = 1.0f;
|
||||||
|
matrix[0][1] = 0.0f;
|
||||||
|
matrix[0][2] = 0.0f;
|
||||||
|
matrix[0][3] = 0.0f;
|
||||||
|
matrix[1][0] = 0.0f;
|
||||||
|
matrix[1][1] = -N[2];
|
||||||
|
matrix[1][2] = -N[0];
|
||||||
|
matrix[1][3] = N[1];
|
||||||
|
matrix[2][0] = 0.0f;
|
||||||
|
matrix[2][1] = U[2];
|
||||||
|
matrix[2][2] = U[0];
|
||||||
|
matrix[2][3] = -U[1];
|
||||||
|
matrix[3][0] = 0.0f;
|
||||||
|
matrix[3][1] = -V[2];
|
||||||
|
matrix[3][2] = -V[0];
|
||||||
|
matrix[3][3] = V[1];
|
||||||
|
|
||||||
for(c = 0;c < num_channels;c++)
|
for(c = 0;c < num_channels;c++)
|
||||||
{
|
{
|
||||||
MixGains *gains = voice->Direct.Mix.Gains[c];
|
MixGains *gains = voice->Direct.Mix.Gains[c];
|
||||||
ALfloat Target[MaxChannels];
|
ALfloat Target[MaxChannels];
|
||||||
|
|
||||||
ComputeBFormatGains(Device, c, DryGain, Target);
|
ComputeBFormatGains(Device, matrix[c], DryGain, Target);
|
||||||
for(i = 0;i < MaxChannels;i++)
|
for(i = 0;i < MaxChannels;i++)
|
||||||
gains[i].Target = Target[i];
|
gains[i].Target = Target[i];
|
||||||
}
|
}
|
||||||
|
@ -81,16 +81,18 @@ void ComputeDirectionalGains(const ALCdevice *device, const ALfloat dir[3], ALfl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeBFormatGains(const ALCdevice *device, ALuint channum, ALfloat ingain, ALfloat gains[MaxChannels])
|
void ComputeBFormatGains(const ALCdevice *device, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MaxChannels])
|
||||||
{
|
{
|
||||||
ALuint i;
|
ALuint i, j;
|
||||||
|
|
||||||
for(i = 0;i < MaxChannels;i++)
|
for(i = 0;i < MaxChannels;i++)
|
||||||
gains[i] = 0.0f;
|
gains[i] = 0.0f;
|
||||||
for(i = 0;i < device->NumSpeakers;i++)
|
for(i = 0;i < device->NumSpeakers;i++)
|
||||||
{
|
{
|
||||||
enum Channel chan = device->Speaker[i].ChanName;
|
enum Channel chan = device->Speaker[i].ChanName;
|
||||||
gains[chan] = device->Speaker[i].FOACoeff[channum] * ingain;
|
for(j = 0;j < 4;j++)
|
||||||
|
gains[chan] += device->Speaker[i].FOACoeff[j] * mtx[j];
|
||||||
|
gains[chan] *= ingain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ typedef struct ALsource {
|
|||||||
volatile ALfloat Position[3];
|
volatile ALfloat Position[3];
|
||||||
volatile ALfloat Velocity[3];
|
volatile ALfloat Velocity[3];
|
||||||
volatile ALfloat Direction[3];
|
volatile ALfloat Direction[3];
|
||||||
|
volatile ALfloat Orientation[2][3];
|
||||||
volatile ALboolean HeadRelative;
|
volatile ALboolean HeadRelative;
|
||||||
volatile ALboolean Looping;
|
volatile ALboolean Looping;
|
||||||
volatile enum DistanceModel DistanceModel;
|
volatile enum DistanceModel DistanceModel;
|
||||||
|
@ -220,10 +220,11 @@ void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat elevation
|
|||||||
/**
|
/**
|
||||||
* ComputeBFormatGains
|
* ComputeBFormatGains
|
||||||
*
|
*
|
||||||
* Sets channel gains for a given (first-order) B-Format channel. The channel
|
* Sets channel gains for a given (first-order) B-Format channel. The matrix is
|
||||||
* number must not be greater than 4, and the resulting gains may be negative.
|
* a 1x4 'slice' of the rotation matrix for a given channel used to orient the
|
||||||
|
* coefficients.
|
||||||
*/
|
*/
|
||||||
void ComputeBFormatGains(const ALCdevice *device, ALuint channum, ALfloat ingain, ALfloat gains[MaxChannels]);
|
void ComputeBFormatGains(const ALCdevice *device, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MaxChannels]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetGains
|
* SetGains
|
||||||
|
@ -108,6 +108,9 @@ typedef enum SrcFloatProp {
|
|||||||
|
|
||||||
/* AL_SOFT_source_latency */
|
/* AL_SOFT_source_latency */
|
||||||
sfSecOffsetLatencySOFT = AL_SEC_OFFSET_LATENCY_SOFT,
|
sfSecOffsetLatencySOFT = AL_SEC_OFFSET_LATENCY_SOFT,
|
||||||
|
|
||||||
|
/* AL_EXT_BFORMAT */
|
||||||
|
sfOrientation = AL_ORIENTATION,
|
||||||
} SrcFloatProp;
|
} SrcFloatProp;
|
||||||
|
|
||||||
typedef enum SrcIntProp {
|
typedef enum SrcIntProp {
|
||||||
@ -153,6 +156,9 @@ typedef enum SrcIntProp {
|
|||||||
|
|
||||||
/* AL_SOFT_source_latency */
|
/* AL_SOFT_source_latency */
|
||||||
siSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT,
|
siSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT,
|
||||||
|
|
||||||
|
/* AL_EXT_BFORMAT */
|
||||||
|
siOrientation = AL_ORIENTATION,
|
||||||
} SrcIntProp;
|
} SrcIntProp;
|
||||||
|
|
||||||
static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values);
|
static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values);
|
||||||
@ -210,6 +216,9 @@ static ALint FloatValsByProp(ALenum prop)
|
|||||||
case sfDirection:
|
case sfDirection:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
case sfOrientation:
|
||||||
|
return 6;
|
||||||
|
|
||||||
case sfSecOffsetLatencySOFT:
|
case sfSecOffsetLatencySOFT:
|
||||||
break; /* Double only */
|
break; /* Double only */
|
||||||
}
|
}
|
||||||
@ -262,6 +271,9 @@ static ALint DoubleValsByProp(ALenum prop)
|
|||||||
case sfVelocity:
|
case sfVelocity:
|
||||||
case sfDirection:
|
case sfDirection:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
case sfOrientation:
|
||||||
|
return 6;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -308,6 +320,9 @@ static ALint IntValsByProp(ALenum prop)
|
|||||||
case siAuxSendFilter:
|
case siAuxSendFilter:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
case siOrientation:
|
||||||
|
return 6;
|
||||||
|
|
||||||
case siSampleOffsetLatencySOFT:
|
case siSampleOffsetLatencySOFT:
|
||||||
break; /* i64 only */
|
break; /* i64 only */
|
||||||
}
|
}
|
||||||
@ -355,6 +370,9 @@ static ALint Int64ValsByProp(ALenum prop)
|
|||||||
case siDirection:
|
case siDirection:
|
||||||
case siAuxSendFilter:
|
case siAuxSendFilter:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
case siOrientation:
|
||||||
|
return 6;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -530,6 +548,20 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp
|
|||||||
ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
|
ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
|
||||||
return AL_TRUE;
|
return AL_TRUE;
|
||||||
|
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) &&
|
||||||
|
isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]));
|
||||||
|
|
||||||
|
LockContext(Context);
|
||||||
|
Source->Orientation[0][0] = values[0];
|
||||||
|
Source->Orientation[0][1] = values[1];
|
||||||
|
Source->Orientation[0][2] = values[2];
|
||||||
|
Source->Orientation[1][0] = values[3];
|
||||||
|
Source->Orientation[1][1] = values[4];
|
||||||
|
Source->Orientation[1][2] = values[5];
|
||||||
|
UnlockContext(Context);
|
||||||
|
ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
|
||||||
|
return AL_TRUE;
|
||||||
|
|
||||||
case sfSampleRWOffsetsSOFT:
|
case sfSampleRWOffsetsSOFT:
|
||||||
case sfByteRWOffsetsSOFT:
|
case sfByteRWOffsetsSOFT:
|
||||||
@ -567,7 +599,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
|||||||
ALeffectslot *slot = NULL;
|
ALeffectslot *slot = NULL;
|
||||||
ALbufferlistitem *oldlist;
|
ALbufferlistitem *oldlist;
|
||||||
ALbufferlistitem *newlist;
|
ALbufferlistitem *newlist;
|
||||||
ALfloat fvals[3];
|
ALfloat fvals[6];
|
||||||
|
|
||||||
switch(prop)
|
switch(prop)
|
||||||
{
|
{
|
||||||
@ -791,6 +823,15 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
|||||||
fvals[2] = (ALfloat)values[2];
|
fvals[2] = (ALfloat)values[2];
|
||||||
return SetSourcefv(Source, Context, (int)prop, fvals);
|
return SetSourcefv(Source, Context, (int)prop, fvals);
|
||||||
|
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
fvals[0] = (ALfloat)values[0];
|
||||||
|
fvals[1] = (ALfloat)values[1];
|
||||||
|
fvals[2] = (ALfloat)values[2];
|
||||||
|
fvals[3] = (ALfloat)values[3];
|
||||||
|
fvals[4] = (ALfloat)values[4];
|
||||||
|
fvals[5] = (ALfloat)values[5];
|
||||||
|
return SetSourcefv(Source, Context, (int)prop, fvals);
|
||||||
|
|
||||||
case siSampleOffsetLatencySOFT:
|
case siSampleOffsetLatencySOFT:
|
||||||
/* i64 only */
|
/* i64 only */
|
||||||
break;
|
break;
|
||||||
@ -802,7 +843,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
|||||||
|
|
||||||
static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values)
|
static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values)
|
||||||
{
|
{
|
||||||
ALfloat fvals[3];
|
ALfloat fvals[6];
|
||||||
ALint ivals[3];
|
ALint ivals[3];
|
||||||
|
|
||||||
switch(prop)
|
switch(prop)
|
||||||
@ -873,6 +914,16 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp
|
|||||||
fvals[1] = (ALfloat)values[1];
|
fvals[1] = (ALfloat)values[1];
|
||||||
fvals[2] = (ALfloat)values[2];
|
fvals[2] = (ALfloat)values[2];
|
||||||
return SetSourcefv(Source, Context, (int)prop, fvals);
|
return SetSourcefv(Source, Context, (int)prop, fvals);
|
||||||
|
|
||||||
|
/* 6x float */
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
fvals[0] = (ALfloat)values[0];
|
||||||
|
fvals[1] = (ALfloat)values[1];
|
||||||
|
fvals[2] = (ALfloat)values[2];
|
||||||
|
fvals[3] = (ALfloat)values[3];
|
||||||
|
fvals[4] = (ALfloat)values[4];
|
||||||
|
fvals[5] = (ALfloat)values[5];
|
||||||
|
return SetSourcefv(Source, Context, (int)prop, fvals);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("Unexpected property: 0x%04x\n", prop);
|
ERR("Unexpected property: 0x%04x\n", prop);
|
||||||
@ -1025,6 +1076,17 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SrcFloatProp
|
|||||||
UnlockContext(Context);
|
UnlockContext(Context);
|
||||||
return AL_TRUE;
|
return AL_TRUE;
|
||||||
|
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
LockContext(Context);
|
||||||
|
values[0] = Source->Orientation[0][0];
|
||||||
|
values[1] = Source->Orientation[0][1];
|
||||||
|
values[2] = Source->Orientation[0][2];
|
||||||
|
values[3] = Source->Orientation[1][0];
|
||||||
|
values[4] = Source->Orientation[1][1];
|
||||||
|
values[5] = Source->Orientation[1][2];
|
||||||
|
UnlockContext(Context);
|
||||||
|
return AL_TRUE;
|
||||||
|
|
||||||
case AL_SOURCE_RELATIVE:
|
case AL_SOURCE_RELATIVE:
|
||||||
case AL_LOOPING:
|
case AL_LOOPING:
|
||||||
case AL_BUFFER:
|
case AL_BUFFER:
|
||||||
@ -1049,7 +1111,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SrcFloatProp
|
|||||||
static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values)
|
static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values)
|
||||||
{
|
{
|
||||||
ALbufferlistitem *BufferList;
|
ALbufferlistitem *BufferList;
|
||||||
ALdouble dvals[3];
|
ALdouble dvals[6];
|
||||||
ALboolean err;
|
ALboolean err;
|
||||||
|
|
||||||
switch(prop)
|
switch(prop)
|
||||||
@ -1224,6 +1286,18 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE)
|
||||||
|
{
|
||||||
|
values[0] = (ALint)dvals[0];
|
||||||
|
values[1] = (ALint)dvals[1];
|
||||||
|
values[2] = (ALint)dvals[2];
|
||||||
|
values[3] = (ALint)dvals[3];
|
||||||
|
values[4] = (ALint)dvals[4];
|
||||||
|
values[5] = (ALint)dvals[5];
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
|
||||||
case siSampleOffsetLatencySOFT:
|
case siSampleOffsetLatencySOFT:
|
||||||
/* i64 only */
|
/* i64 only */
|
||||||
break;
|
break;
|
||||||
@ -1240,7 +1314,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
|||||||
|
|
||||||
static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values)
|
static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values)
|
||||||
{
|
{
|
||||||
ALdouble dvals[3];
|
ALdouble dvals[6];
|
||||||
ALint ivals[3];
|
ALint ivals[3];
|
||||||
ALboolean err;
|
ALboolean err;
|
||||||
|
|
||||||
@ -1288,6 +1362,18 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
case AL_ORIENTATION:
|
||||||
|
if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE)
|
||||||
|
{
|
||||||
|
values[0] = (ALint64)dvals[0];
|
||||||
|
values[1] = (ALint64)dvals[1];
|
||||||
|
values[2] = (ALint64)dvals[2];
|
||||||
|
values[3] = (ALint64)dvals[3];
|
||||||
|
values[4] = (ALint64)dvals[4];
|
||||||
|
values[5] = (ALint64)dvals[5];
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
|
||||||
case AL_SOURCE_RELATIVE:
|
case AL_SOURCE_RELATIVE:
|
||||||
case AL_LOOPING:
|
case AL_LOOPING:
|
||||||
case AL_SOURCE_STATE:
|
case AL_SOURCE_STATE:
|
||||||
@ -2381,12 +2467,18 @@ static ALvoid InitSourceParams(ALsource *Source)
|
|||||||
Source->Position[0] = 0.0f;
|
Source->Position[0] = 0.0f;
|
||||||
Source->Position[1] = 0.0f;
|
Source->Position[1] = 0.0f;
|
||||||
Source->Position[2] = 0.0f;
|
Source->Position[2] = 0.0f;
|
||||||
Source->Direction[0] = 0.0f;
|
|
||||||
Source->Direction[1] = 0.0f;
|
|
||||||
Source->Direction[2] = 0.0f;
|
|
||||||
Source->Velocity[0] = 0.0f;
|
Source->Velocity[0] = 0.0f;
|
||||||
Source->Velocity[1] = 0.0f;
|
Source->Velocity[1] = 0.0f;
|
||||||
Source->Velocity[2] = 0.0f;
|
Source->Velocity[2] = 0.0f;
|
||||||
|
Source->Direction[0] = 0.0f;
|
||||||
|
Source->Direction[1] = 0.0f;
|
||||||
|
Source->Direction[2] = 0.0f;
|
||||||
|
Source->Orientation[0][0] = 0.0f;
|
||||||
|
Source->Orientation[0][1] = 0.0f;
|
||||||
|
Source->Orientation[0][2] = -1.0f;
|
||||||
|
Source->Orientation[1][0] = 0.0f;
|
||||||
|
Source->Orientation[1][1] = 1.0f;
|
||||||
|
Source->Orientation[1][2] = 0.0f;
|
||||||
Source->RefDistance = 1.0f;
|
Source->RefDistance = 1.0f;
|
||||||
Source->MaxDistance = FLT_MAX;
|
Source->MaxDistance = FLT_MAX;
|
||||||
Source->RollOffFactor = 1.0f;
|
Source->RollOffFactor = 1.0f;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user