diff options
author | Chris Robinson <[email protected]> | 2014-10-31 22:43:13 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-10-31 22:43:13 -0700 |
commit | 3d2853274dbf81723b907677446bd09f94f35022 (patch) | |
tree | 6f6001476326386c838a61da0fb9775a6705d390 | |
parent | 336aba6f1f9bc21d900435a264c048a36bca0fc8 (diff) |
Support B-Format source rotation with AL_ORIENTATION
-rw-r--r-- | Alc/ALu.c | 43 | ||||
-rw-r--r-- | Alc/panning.c | 8 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 1 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 7 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 106 |
5 files changed, 151 insertions, 14 deletions
@@ -288,6 +288,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ALfloat WetGainHF[MAX_SENDS]; ALfloat WetGainLF[MAX_SENDS]; ALuint NumSends, Frequency; + ALboolean Relative; const struct ChanMap *chans = NULL; ALuint num_channels = 0; ALboolean DirectChannels; @@ -307,6 +308,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A MinVolume = ALSource->MinGain; MaxVolume = ALSource->MaxGain; Pitch = ALSource->Pitch; + Relative = ALSource->HeadRelative; DirectChannels = ALSource->DirectChannels; voice->Direct.OutBuffer = Device->DryBuffer; @@ -414,12 +416,51 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A 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++) { MixGains *gains = voice->Direct.Mix.Gains[c]; ALfloat Target[MaxChannels]; - ComputeBFormatGains(Device, c, DryGain, Target); + ComputeBFormatGains(Device, matrix[c], DryGain, Target); for(i = 0;i < MaxChannels;i++) gains[i].Target = Target[i]; } diff --git a/Alc/panning.c b/Alc/panning.c index 85de3626..ad8ad43b 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -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++) gains[i] = 0.0f; for(i = 0;i < device->NumSpeakers;i++) { 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; } } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 34d01e19..96216b87 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -60,6 +60,7 @@ typedef struct ALsource { volatile ALfloat Position[3]; volatile ALfloat Velocity[3]; volatile ALfloat Direction[3]; + volatile ALfloat Orientation[2][3]; volatile ALboolean HeadRelative; volatile ALboolean Looping; volatile enum DistanceModel DistanceModel; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 0bf252f5..6ebafe86 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -220,10 +220,11 @@ void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat elevation /** * ComputeBFormatGains * - * Sets channel gains for a given (first-order) B-Format channel. The channel - * number must not be greater than 4, and the resulting gains may be negative. + * Sets channel gains for a given (first-order) B-Format channel. The matrix is + * 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 diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a148a21a..a716eb74 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -108,6 +108,9 @@ typedef enum SrcFloatProp { /* AL_SOFT_source_latency */ sfSecOffsetLatencySOFT = AL_SEC_OFFSET_LATENCY_SOFT, + + /* AL_EXT_BFORMAT */ + sfOrientation = AL_ORIENTATION, } SrcFloatProp; typedef enum SrcIntProp { @@ -153,6 +156,9 @@ typedef enum SrcIntProp { /* AL_SOFT_source_latency */ siSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT, + + /* AL_EXT_BFORMAT */ + siOrientation = AL_ORIENTATION, } SrcIntProp; static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values); @@ -210,6 +216,9 @@ static ALint FloatValsByProp(ALenum prop) case sfDirection: return 3; + case sfOrientation: + return 6; + case sfSecOffsetLatencySOFT: break; /* Double only */ } @@ -262,6 +271,9 @@ static ALint DoubleValsByProp(ALenum prop) case sfVelocity: case sfDirection: return 3; + + case sfOrientation: + return 6; } return 0; } @@ -308,6 +320,9 @@ static ALint IntValsByProp(ALenum prop) case siAuxSendFilter: return 3; + case siOrientation: + return 6; + case siSampleOffsetLatencySOFT: break; /* i64 only */ } @@ -355,6 +370,9 @@ static ALint Int64ValsByProp(ALenum prop) case siDirection: case siAuxSendFilter: return 3; + + case siOrientation: + return 6; } return 0; } @@ -530,6 +548,20 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp ATOMIC_STORE(&Source->NeedsUpdate, 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 sfByteRWOffsetsSOFT: @@ -567,7 +599,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p ALeffectslot *slot = NULL; ALbufferlistitem *oldlist; ALbufferlistitem *newlist; - ALfloat fvals[3]; + ALfloat fvals[6]; switch(prop) { @@ -791,6 +823,15 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p fvals[2] = (ALfloat)values[2]; 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: /* i64 only */ 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) { - ALfloat fvals[3]; + ALfloat fvals[6]; ALint ivals[3]; switch(prop) @@ -873,6 +914,16 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp fvals[1] = (ALfloat)values[1]; fvals[2] = (ALfloat)values[2]; 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); @@ -1025,6 +1076,17 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SrcFloatProp UnlockContext(Context); 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_LOOPING: 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) { ALbufferlistitem *BufferList; - ALdouble dvals[3]; + ALdouble dvals[6]; ALboolean err; switch(prop) @@ -1224,6 +1286,18 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p } 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: /* i64 only */ 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) { - ALdouble dvals[3]; + ALdouble dvals[6]; ALint ivals[3]; ALboolean err; @@ -1288,6 +1362,18 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp } 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_LOOPING: case AL_SOURCE_STATE: @@ -2381,12 +2467,18 @@ static ALvoid InitSourceParams(ALsource *Source) Source->Position[0] = 0.0f; Source->Position[1] = 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[1] = 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->MaxDistance = FLT_MAX; Source->RollOffFactor = 1.0f; |