diff options
-rw-r--r-- | Alc/ALu.c | 125 | ||||
-rw-r--r-- | Alc/mixer.c | 5 | ||||
-rw-r--r-- | Alc/mixer_c.c | 13 | ||||
-rw-r--r-- | Alc/mixer_defs.h | 21 | ||||
-rw-r--r-- | Alc/mixer_neon.c | 13 | ||||
-rw-r--r-- | Alc/mixer_sse.c | 13 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 25 |
7 files changed, 119 insertions, 96 deletions
@@ -413,20 +413,28 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext) if(DirectChannels != AL_FALSE) { - ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains.Target; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { - for(c = 0;c < MaxChannels;c++) - Matrix[i][c] = 0.0f; + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + ALfloat *restrict Target = src->Direct.Mix.Gains[i].Target; + for(j = 0;j < MaxChannels;j++) + { + Current[j] = 0.0f; + Step[j] = 1.0f; + Target[j] = 0.0f; + } } + for(c = 0;c < num_channels;c++) { + ALfloat *restrict Target = src->Direct.Mix.Gains[c].Target; for(i = 0;i < (ALint)Device->NumChan;i++) { enum Channel chan = Device->Speaker2Chan[i]; if(chan == chans[c].channel) { - Matrix[c][chan] = DryGain; + Target[chan] = DryGain; break; } } @@ -434,33 +442,35 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext) if(src->Direct.Moving) { - ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current; - ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + ALfloat *restrict Target = src->Direct.Mix.Gains[i].Target; for(j = 0;j < MaxChannels;j++) { - ALfloat cur = maxf(Current[i][j], FLT_EPSILON); - ALfloat trg = maxf(Matrix[i][j], FLT_EPSILON); + ALfloat cur = maxf(Current[j], FLT_EPSILON); + ALfloat trg = maxf(Target[j], FLT_EPSILON); if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - Step[i][j] = powf(trg/cur, 1.0f/64.0f); + Step[j] = powf(trg/cur, 1.0f/64.0f); else - Step[i][j] = 1.0f; - Current[i][j] = cur; + Step[j] = 1.0f; + Current[j] = cur; } } src->Direct.Counter = 64; } else { - ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current; - ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + ALfloat *restrict Target = src->Direct.Mix.Gains[i].Target; for(j = 0;j < MaxChannels;j++) { - Current[i][j] = Matrix[i][j]; - Step[i][j] = 1.0f; + Current[j] = Target[j]; + Step[j] = 1.0f; } } src->Direct.Counter = 0; @@ -504,55 +514,63 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext) } else { - ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains.Target; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { - for(c = 0;c < MaxChannels;c++) - Matrix[i][c] = 0.0f; + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + ALfloat *restrict Target = src->Direct.Mix.Gains[i].Target; + for(j = 0;j < MaxChannels;j++) + { + Current[j] = 0.0f; + Step[j] = 1.0f; + Target[j] = 0.0f; + } } DryGain *= lerp(1.0f, 1.0f/sqrtf((float)Device->NumChan), hwidth/F_PI); for(c = 0;c < num_channels;c++) { + ALfloat *restrict Target = src->Direct.Mix.Gains[c].Target; /* Special-case LFE */ if(chans[c].channel == LFE) { - Matrix[c][chans[c].channel] = DryGain; + Target[chans[c].channel] = DryGain; continue; } - ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain, - Matrix[c]); + ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain, Target); } if(src->Direct.Moving) { - ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current; - ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + ALfloat *restrict Target = src->Direct.Mix.Gains[i].Target; for(j = 0;j < MaxChannels;j++) { - ALfloat trg = maxf(Matrix[i][j], FLT_EPSILON); - ALfloat cur = maxf(Current[i][j], FLT_EPSILON); + ALfloat trg = maxf(Target[j], FLT_EPSILON); + ALfloat cur = maxf(Current[j], FLT_EPSILON); if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - Step[i][j] = powf(trg/cur, 1.0f/64.0f); + Step[j] = powf(trg/cur, 1.0f/64.0f); else - Step[i][j] = 1.0f; - Current[i][j] = cur; + Step[j] = 1.0f; + Current[j] = cur; } } src->Direct.Counter = 64; } else { - ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current; - ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + ALfloat *restrict Target = src->Direct.Mix.Gains[i].Target; for(j = 0;j < MaxChannels;j++) { - Current[i][j] = Matrix[i][j]; - Step[i][j] = 1.0f; + Current[j] = Target[j]; + Step[j] = 1.0f; } } src->Direct.Counter = 0; @@ -1028,15 +1046,23 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext) } else { - ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains.Target; + ALfloat *restrict Target; ALfloat DirGain = 0.0f; ALfloat AmbientGain; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { + ALfloat *restrict Current = src->Direct.Mix.Gains[i].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[i].Step; + Target = src->Direct.Mix.Gains[i].Target; for(j = 0;j < MaxChannels;j++) - Matrix[i][j] = 0.0f; + { + Current[j] = 0.0f; + Step[j] = 1.0f; + Target[j] = 0.0f; + } } + Target = src->Direct.Mix.Gains[0].Target; /* Normalize the length, and compute panned gains. */ if(Distance > FLT_EPSILON) @@ -1048,7 +1074,7 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext) DirGain = sqrtf(Position[0]*Position[0] + Position[2]*Position[2]); ComputeAngleGains(Device, atan2f(Position[0], -Position[2]*ZScale), 0.0f, - DryGain*DirGain, Matrix[0]); + DryGain*DirGain, Target); } /* Adjustment for vertical offsets. Not the greatest, but simple @@ -1057,36 +1083,33 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext) for(i = 0;i < (ALint)Device->NumChan;i++) { enum Channel chan = Device->Speaker2Chan[i]; - Matrix[0][chan] = maxf(Matrix[0][chan], AmbientGain); + Target[chan] = maxf(Target[chan], AmbientGain); } if(src->Direct.Moving) { - ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current; - ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step; + ALfloat *restrict Current = src->Direct.Mix.Gains[0].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[0].Step; for(j = 0;j < MaxChannels;j++) { - ALfloat cur = maxf(Current[0][j], FLT_EPSILON); - ALfloat trg = maxf(Matrix[0][j], FLT_EPSILON); + ALfloat cur = maxf(Current[j], FLT_EPSILON); + ALfloat trg = maxf(Target[j], FLT_EPSILON); if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - Step[0][j] = powf(trg/cur, 1.0f/64.0f); + Step[j] = powf(trg/cur, 1.0f/64.0f); else - Step[0][j] = 1.0f; - Current[0][j] = cur; + Step[j] = 1.0f; + Current[j] = cur; } src->Direct.Counter = 64; } else { - ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current; - ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step; - for(i = 0;i < MAX_INPUT_CHANNELS;i++) + ALfloat *restrict Current = src->Direct.Mix.Gains[0].Current; + ALfloat *restrict Step = src->Direct.Mix.Gains[0].Step; + for(j = 0;j < MaxChannels;j++) { - for(j = 0;j < MaxChannels;j++) - { - Current[i][j] = Matrix[i][j]; - Step[i][j] = 1.0f; - } + Current[j] = Target[j]; + Step[j] = 1.0f; } src->Direct.Counter = 0; src->Direct.Moving = AL_TRUE; diff --git a/Alc/mixer.c b/Alc/mixer.c index e1be5fd9..e5ee4a45 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -351,8 +351,9 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo) SrcData, ResampledData, DstBufferSize, directparms->Filters[chan]); if(!src->IsHrtf) - src->Dry.Mix(directparms, directparms->OutBuffer, SrcData, - maxu(directparms->Counter, OutPos) - OutPos, chan, + src->Dry.Mix(directparms->OutBuffer, SrcData, + &directparms->Mix.Gains[chan], + maxu(directparms->Counter, OutPos) - OutPos, OutPos, DstBufferSize); else src->Dry.HrtfMix(directparms->OutBuffer, SrcData, diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c index 3db4f737..700b326b 100644 --- a/Alc/mixer_c.c +++ b/Alc/mixer_c.c @@ -90,9 +90,8 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], #undef SUFFIX -void MixDirect_C(DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *restrict data, - ALuint Counter, ALuint srcchan, ALuint OutPos, ALuint BufferSize) +void MixDirect_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize) { ALfloat DrySend, Step; ALuint c; @@ -100,8 +99,8 @@ void MixDirect_C(DirectParams *params, for(c = 0;c < MaxChannels;c++) { ALuint pos = 0; - DrySend = params->Mix.Gains.Current[srcchan][c]; - Step = params->Mix.Gains.Step[srcchan][c]; + DrySend = Gains->Current[c]; + Step = Gains->Step[c]; if(Step != 1.0f && Counter > 0) { for(;pos < BufferSize && pos < Counter;pos++) @@ -110,8 +109,8 @@ void MixDirect_C(DirectParams *params, DrySend *= Step; } if(pos == Counter) - DrySend = params->Mix.Gains.Target[srcchan][c]; - params->Mix.Gains.Current[srcchan][c] = DrySend; + DrySend = Gains->Target[c]; + Gains->Current[c] = DrySend; } if(!(DrySend > GAIN_SILENCE_THRESHOLD)) diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h index c1d90408..8f5375f4 100644 --- a/Alc/mixer_defs.h +++ b/Alc/mixer_defs.h @@ -5,9 +5,10 @@ #include "AL/al.h" #include "alMain.h" -struct DirectParams; struct SendParams; +struct MixGains; + struct HrtfParams; struct HrtfState; @@ -23,9 +24,9 @@ void MixDirect_Hrtf_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat * ALuint Counter, ALuint Offset, const ALuint IrSize, const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, ALuint OutPos, ALuint BufferSize); -void MixDirect_C(struct DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *restrict data, - ALuint Counter, ALuint srcchan, ALuint OutPos, ALuint BufferSize); +void MixDirect_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + struct MixGains *Gains, ALuint Counter, ALuint OutPos, + ALuint BufferSize); void MixSend_C(struct SendParams*,const ALfloat*restrict,ALuint,ALuint); /* SSE mixers */ @@ -33,9 +34,9 @@ void MixDirect_Hrtf_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat ALuint Counter, ALuint Offset, const ALuint IrSize, const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, ALuint OutPos, ALuint BufferSize); -void MixDirect_SSE(struct DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *restrict data, - ALuint Counter, ALuint srcchan, ALuint OutPos, ALuint BufferSize); +void MixDirect_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + struct MixGains *Gains, ALuint Counter, ALuint OutPos, + ALuint BufferSize); void MixSend_SSE(struct SendParams*,const ALfloat*restrict,ALuint,ALuint); /* Neon mixers */ @@ -43,9 +44,9 @@ void MixDirect_Hrtf_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloa ALuint Counter, ALuint Offset, const ALuint IrSize, const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, ALuint OutPos, ALuint BufferSize); -void MixDirect_Neon(struct DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *restrict data, - ALuint Counter, ALuint srcchan, ALuint OutPos, ALuint BufferSize); +void MixDirect_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + struct MixGains *Gains, ALuint Counter, ALuint OutPos, + ALuint BufferSize); void MixSend_Neon(struct SendParams*,const ALfloat*restrict,ALuint,ALuint); #endif /* MIXER_DEFS_H */ diff --git a/Alc/mixer_neon.c b/Alc/mixer_neon.c index 161c19c8..1fc56e53 100644 --- a/Alc/mixer_neon.c +++ b/Alc/mixer_neon.c @@ -75,9 +75,8 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], #undef SUFFIX -void MixDirect_Neon(DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *restrict data, - ALuint Counter, ALuint srcchan, ALuint OutPos, ALuint BufferSize) +void MixDirect_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize) { ALfloat DrySend, Step; float32x4_t gain; @@ -86,8 +85,8 @@ void MixDirect_Neon(DirectParams *params, for(c = 0;c < MaxChannels;c++) { ALuint pos = 0; - DrySend = params->Mix.Gains.Current[srcchan][c]; - Step = params->Mix.Gains.Step[srcchan][c]; + DrySend = Gains->Current[c]; + Step = Gains->Step[c]; if(Step != 1.0f && Counter > 0) { for(;pos < BufferSize && pos < Counter;pos++) @@ -96,8 +95,8 @@ void MixDirect_Neon(DirectParams *params, DrySend *= Step; } if(pos == Counter) - DrySend = params->Mix.Gains.Target[srcchan][c]; - params->Mix.Gains.Current[srcchan][c] = DrySend; + DrySend = Gains->Target[c]; + Gains->Current[c] = DrySend; /* Mix until pos is aligned with 4 or the mix is done. */ for(;pos < BufferSize && (pos&3) != 0;pos++) OutBuffer[c][OutPos+pos] += data[pos]*DrySend; diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c index e33b3ef3..21234f0f 100644 --- a/Alc/mixer_sse.c +++ b/Alc/mixer_sse.c @@ -138,9 +138,8 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], #undef SUFFIX -void MixDirect_SSE(DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *restrict data, - ALuint Counter, ALuint srcchan, ALuint OutPos, ALuint BufferSize) +void MixDirect_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize) { ALfloat DrySend, Step; __m128 gain, step; @@ -149,8 +148,8 @@ void MixDirect_SSE(DirectParams *params, for(c = 0;c < MaxChannels;c++) { ALuint pos = 0; - DrySend = params->Mix.Gains.Current[srcchan][c]; - Step = params->Mix.Gains.Step[srcchan][c]; + DrySend = Gains->Current[c]; + Step = Gains->Step[c]; if(Step != 1.0f && Counter > 0) { /* Mix with applying gain steps in aligned multiples of 4. */ @@ -180,8 +179,8 @@ void MixDirect_SSE(DirectParams *params, DrySend *= Step; } if(pos == Counter) - DrySend = params->Mix.Gains.Target[srcchan][c]; - params->Mix.Gains.Current[srcchan][c] = DrySend; + DrySend = Gains->Target[c]; + Gains->Current[c] = DrySend; /* Mix until pos is aligned with 4 or the mix is done. */ for(;pos < BufferSize && (pos&3) != 0;pos++) OutBuffer[c][OutPos+pos] += data[pos]*DrySend; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 7816ee94..432e9bd3 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -46,6 +46,7 @@ enum ActiveFilters { AF_BandPass = AF_LowPass | AF_HighPass }; + typedef struct HrtfState { alignas(16) ALfloat History[SRC_HISTORY_LENGTH]; alignas(16) ALfloat Values[HRIR_LENGTH][2]; @@ -58,6 +59,14 @@ typedef struct HrtfParams { ALint DelayStep[2]; } HrtfParams; + +typedef struct MixGains { + ALfloat Current[MaxChannels]; + ALfloat Step[MaxChannels]; + ALfloat Target[MaxChannels]; +} MixGains; + + typedef struct DirectParams { ALfloat (*OutBuffer)[BUFFERSIZE]; @@ -81,14 +90,7 @@ typedef struct DirectParams { ALfloat Dir[3]; } Hrtf; - /* A mixing matrix. First subscript is the channel number of the input - * data (regardless of channel configuration) and the second is the - * channel target (eg. FrontLeft). Not used with HRTF. */ - struct { - ALfloat Current[MAX_INPUT_CHANNELS][MaxChannels]; - ALfloat Step[MAX_INPUT_CHANNELS][MaxChannels]; - ALfloat Target[MAX_INPUT_CHANNELS][MaxChannels]; - } Gains; + MixGains Gains[MAX_INPUT_CHANNELS]; } Mix; } DirectParams; @@ -115,10 +117,9 @@ typedef struct SendParams { typedef void (*ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); -typedef ALvoid (*DryMixerFunc)(struct DirectParams *params, - ALfloat (*restrict OutBuffer)[BUFFERSIZE], - const ALfloat *restrict data, ALuint Counter, - ALuint srcchan, ALuint OutPos, ALuint BufferSize); +typedef ALvoid (*DryMixerFunc)(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, + MixGains *Gains, ALuint Counter, ALuint OutPos, + ALuint BufferSize); typedef void (*HrtfMixerFunc)(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, ALuint Counter, ALuint Offset, const ALuint IrSize, const HrtfParams *hrtfparams, HrtfState *hrtfstate, |