diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 14 | ||||
-rw-r--r-- | Alc/ALu.c | 163 | ||||
-rw-r--r-- | Alc/hrtf.c | 222 | ||||
-rw-r--r-- | Alc/hrtf.h | 4 | ||||
-rw-r--r-- | Alc/midi/fluidsynth.c | 8 | ||||
-rw-r--r-- | Alc/mixer.c | 25 | ||||
-rw-r--r-- | Alc/mixer_c.c | 17 | ||||
-rw-r--r-- | Alc/mixer_defs.h | 15 | ||||
-rw-r--r-- | Alc/mixer_inc.c | 54 | ||||
-rw-r--r-- | Alc/mixer_neon.c | 32 | ||||
-rw-r--r-- | Alc/mixer_sse.c | 62 | ||||
-rw-r--r-- | Alc/panning.c | 64 |
12 files changed, 163 insertions, 517 deletions
@@ -1712,6 +1712,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) enum DevFmtType oldType; ALCuint oldFreq; FPUCtl oldMode; + size_t size; // Check for attributes if(device->Type == Loopback) @@ -1885,6 +1886,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if((device->Flags&DEVICE_RUNNING)) return ALC_NO_ERROR; + al_free(device->DryBuffer); + device->DryBuffer = NULL; + UpdateClockBase(device); if(device->Type != Loopback) @@ -1992,11 +1996,15 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) aluInitPanning(device); - al_free(device->DryBuffer); - device->DryBuffer = al_calloc(16, sizeof(device->DryBuffer[0]) * device->NumChannels); + /* With HRTF enabled, the channels are virtual and get positioned around + * the virtual listener. Two extra channels are allocated for the actual + * HRTF-filtered output. + */ + size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0)); + device->DryBuffer = al_calloc(16, size); if(!device->DryBuffer) { - ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", sizeof(device->DryBuffer[0]) * device->NumChannels); + ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size); return ALC_INVALID_DEVICE; } @@ -36,6 +36,8 @@ #include "hrtf.h" #include "static_assert.h" +#include "mixer_defs.h" + #include "backends/base.h" #include "midi/base.h" @@ -83,6 +85,21 @@ extern inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu); extern inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu); +static inline HrtfMixerFunc SelectHrtfMixer(void) +{ +#ifdef HAVE_SSE + if((CPUCapFlags&CPU_CAP_SSE)) + return MixHrtf_SSE; +#endif +#ifdef HAVE_NEON + if((CPUCapFlags&CPU_CAP_NEON)) + return MixHrtf_Neon; +#endif + + return MixHrtf_C; +} + + static inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector) { outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1]; @@ -492,37 +509,6 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A voice->IsHrtf = AL_FALSE; } - else if(Device->Hrtf) - { - for(c = 0;c < num_channels;c++) - { - if(chans[c].channel == LFE) - { - /* Skip LFE */ - voice->Direct.Mix.Hrtf.Params[c].Delay[0] = 0; - voice->Direct.Mix.Hrtf.Params[c].Delay[1] = 0; - for(i = 0;i < HRIR_LENGTH;i++) - { - voice->Direct.Mix.Hrtf.Params[c].Coeffs[i][0] = 0.0f; - voice->Direct.Mix.Hrtf.Params[c].Coeffs[i][1] = 0.0f; - } - } - else - { - /* Get the static HRIR coefficients and delays for this - * channel. */ - GetLerpedHrtfCoeffs(Device->Hrtf, - chans[c].elevation, chans[c].angle, 1.0f, DryGain, - voice->Direct.Mix.Hrtf.Params[c].Coeffs, - voice->Direct.Mix.Hrtf.Params[c].Delay); - } - } - voice->Direct.Counter = 0; - voice->Direct.Moving = AL_TRUE; - voice->Direct.Mix.Hrtf.IrSize = GetHrtfIrSize(Device->Hrtf); - - voice->IsHrtf = AL_TRUE; - } else { for(c = 0;c < num_channels;c++) @@ -929,70 +915,6 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte BufferListItem = BufferListItem->next; } - if(Device->Hrtf) - { - /* Use a binaural HRTF algorithm for stereo headphone playback */ - ALfloat delta, ev = 0.0f, az = 0.0f; - ALfloat radius = ALSource->Radius; - ALfloat dirfact = 1.0f; - - if(Distance > FLT_EPSILON) - { - ALfloat invlen = 1.0f/Distance; - Position[0] *= invlen; - Position[1] *= invlen; - Position[2] *= invlen; - - /* Calculate elevation and azimuth only when the source is not at - * the listener. This prevents +0 and -0 Z from producing - * inconsistent panning. Also, clamp Y in case FP precision errors - * cause it to land outside of -1..+1. */ - ev = asinf(clampf(Position[1], -1.0f, 1.0f)); - az = atan2f(Position[0], -Position[2]*ZScale); - } - if(radius > Distance) - dirfact *= Distance / radius; - - /* Check to see if the HRIR is already moving. */ - if(voice->Direct.Moving) - { - /* Calculate the normalized HRTF transition factor (delta). */ - delta = CalcHrtfDelta(voice->Direct.Mix.Hrtf.Gain, DryGain, - voice->Direct.Mix.Hrtf.Dir, Position); - /* If the delta is large enough, get the moving HRIR target - * coefficients, target delays, steppping values, and counter. */ - if(delta > 0.001f) - { - ALuint counter = GetMovingHrtfCoeffs(Device->Hrtf, - ev, az, dirfact, DryGain, delta, voice->Direct.Counter, - voice->Direct.Mix.Hrtf.Params[0].Coeffs, voice->Direct.Mix.Hrtf.Params[0].Delay, - voice->Direct.Mix.Hrtf.Params[0].CoeffStep, voice->Direct.Mix.Hrtf.Params[0].DelayStep - ); - voice->Direct.Counter = counter; - voice->Direct.Mix.Hrtf.Gain = DryGain; - voice->Direct.Mix.Hrtf.Dir[0] = Position[0]; - voice->Direct.Mix.Hrtf.Dir[1] = Position[1]; - voice->Direct.Mix.Hrtf.Dir[2] = Position[2]; - } - } - else - { - /* Get the initial (static) HRIR coefficients and delays. */ - GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, dirfact, DryGain, - voice->Direct.Mix.Hrtf.Params[0].Coeffs, - voice->Direct.Mix.Hrtf.Params[0].Delay); - voice->Direct.Counter = 0; - voice->Direct.Moving = AL_TRUE; - voice->Direct.Mix.Hrtf.Gain = DryGain; - voice->Direct.Mix.Hrtf.Dir[0] = Position[0]; - voice->Direct.Mix.Hrtf.Dir[1] = Position[1]; - voice->Direct.Mix.Hrtf.Dir[2] = Position[2]; - } - voice->Direct.Mix.Hrtf.IrSize = GetHrtfIrSize(Device->Hrtf); - - voice->IsHrtf = AL_TRUE; - } - else { MixGains *gains = voice->Direct.Mix.Gains[0]; ALfloat radius = ALSource->Radius; @@ -1125,14 +1047,24 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) while(size > 0) { + ALuint outchanoffset = 0; + ALuint outchancount = device->NumChannels; + IncrementRef(&device->MixCount); SamplesToDo = minu(size, BUFFERSIZE); for(c = 0;c < device->NumChannels;c++) memset(device->DryBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); + if(device->Hrtf) + { + outchanoffset = device->NumChannels; + outchancount = 2; + for(c = 0;c < outchancount;c++) + memset(device->DryBuffer[outchanoffset+c], 0, SamplesToDo*sizeof(ALfloat)); + } V0(device->Backend,lock)(); - V(device->Synth,process)(SamplesToDo, device->DryBuffer); + V(device->Synth,process)(SamplesToDo, &device->DryBuffer[outchanoffset]); ctx = ATOMIC_LOAD(&device->ContextList); while(ctx) @@ -1212,7 +1144,16 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) device->SamplesDone %= device->Frequency; V0(device->Backend,unlock)(); - if(device->Bs2b) + if(device->Hrtf) + { + HrtfMixerFunc HrtfMix = SelectHrtfMixer(); + ALuint irsize = GetHrtfIrSize(device->Hrtf); + for(c = 0;c < device->NumChannels;c++) + HrtfMix(&device->DryBuffer[outchanoffset], device->DryBuffer[c], device->Hrtf_Offset, irsize, + &device->Hrtf_Params[c], &device->Hrtf_State[c], SamplesToDo); + device->Hrtf_Offset += SamplesToDo; + } + else if(device->Bs2b) { /* Apply binaural/crossfeed filter */ for(i = 0;i < SamplesToDo;i++) @@ -1231,32 +1172,32 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) switch(device->FmtType) { case DevFmtByte: - Write_ALbyte(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALbyte); + Write_ALbyte(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALbyte); break; case DevFmtUByte: - Write_ALubyte(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALubyte); + Write_ALubyte(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALubyte); break; case DevFmtShort: - Write_ALshort(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALshort); + Write_ALshort(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALshort); break; case DevFmtUShort: - Write_ALushort(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALushort); + Write_ALushort(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALushort); break; case DevFmtInt: - Write_ALint(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALint); + Write_ALint(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALint); break; case DevFmtUInt: - Write_ALuint(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALuint); + Write_ALuint(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALuint); break; case DevFmtFloat: - Write_ALfloat(device->DryBuffer, buffer, SamplesToDo, device->NumChannels); - buffer = (char*)buffer + SamplesToDo*device->NumChannels*sizeof(ALfloat); + Write_ALfloat(&device->DryBuffer[outchanoffset], buffer, SamplesToDo, outchancount); + buffer = (char*)buffer + SamplesToDo*outchancount*sizeof(ALfloat); break; } } @@ -58,10 +58,6 @@ struct Hrtf { static const ALchar magicMarker00[8] = "MinPHR00"; static const ALchar magicMarker01[8] = "MinPHR01"; -/* First value for pass-through coefficients (remaining are 0), used for omni- - * directional sounds. */ -static const ALfloat PassthruCoeff = 32767.0f * 0.707106781187f/*sqrt(0.5)*/; - static struct Hrtf *LoadedHrtfs = NULL; /* Calculate the elevation indices given the polar elevation in radians. @@ -88,45 +84,12 @@ static void CalcAzIndices(ALuint azcount, ALfloat az, ALuint *azidx, ALfloat *az *azmu = az - floorf(az); } -/* Calculates the normalized HRTF transition factor (delta) from the changes - * in gain and listener to source angle between updates. The result is a - * normalized delta factor that can be used to calculate moving HRIR stepping - * values. - */ -ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]) -{ - ALfloat gainChange, angleChange, change; - - // Calculate the normalized dB gain change. - newGain = maxf(newGain, 0.0001f); - oldGain = maxf(oldGain, 0.0001f); - gainChange = fabsf(log10f(newGain / oldGain) / log10f(0.0001f)); - - // Calculate the angle change only when there is enough gain to notice it. - angleChange = 0.0f; - if(gainChange > 0.0001f || newGain > 0.0001f) - { - // No angle change when the directions are equal or degenerate (when - // both have zero length). - if(newdir[0] != olddir[0] || newdir[1] != olddir[1] || newdir[2] != olddir[2]) - { - ALfloat dotp = olddir[0]*newdir[0] + olddir[1]*newdir[1] + olddir[2]*newdir[2]; - angleChange = acosf(clampf(dotp, -1.0f, 1.0f)) / F_PI; - } - } - - // Use the largest of the two changes for the delta factor, and apply a - // significance shaping function to it. - change = maxf(angleChange * 25.0f, gainChange) * 2.0f; - return minf(change, 1.0f); -} - /* Calculates static HRIR coefficients and delays for the given polar * elevation and azimuth in radians. Linear interpolation is used to * increase the apparent resolution of the HRIR data set. The coefficients * are also normalized and attenuated by the specified gain. */ -void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays) +void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat (*coeffs)[2], ALuint *delays) { ALuint evidx[2], lidx[4], ridx[4]; ALfloat mu[3], blend[4]; @@ -158,12 +121,12 @@ void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azi blend[3] = ( mu[1]) * ( mu[2]); /* Calculate the HRIR delays using linear interpolation. */ - delays[0] = fastf2u((Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + - Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - delays[1] = fastf2u((Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + - Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; + delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + + Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] + + 0.5f); + delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + + Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] + + 0.5f); /* Calculate the sample offsets for the HRIR indices. */ lidx[0] *= Hrtf->irSize; @@ -175,183 +138,22 @@ void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azi ridx[2] *= Hrtf->irSize; ridx[3] *= Hrtf->irSize; - /* Calculate the normalized and attenuated HRIR coefficients using linear - * interpolation when there is enough gain to warrant it. Zero the - * coefficients if gain is too low. - */ - if(gain > 0.0001f) + for(i = 0;i < Hrtf->irSize;i++) { ALfloat c; - - gain *= 1.0f/32767.0f; - - i = 0; c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(PassthruCoeff, c, dirfact) * gain; + coeffs[i][0] = c * (1.0f/32767.0f); c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(PassthruCoeff, c, dirfact) * gain; - - for(i = 1;i < Hrtf->irSize;i++) - { - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(0.0f, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(0.0f, c, dirfact) * gain; - } + coeffs[i][1] = c * (1.0f/32767.0f); } - else - { - for(i = 0;i < Hrtf->irSize;i++) - { - coeffs[i][0] = 0.0f; - coeffs[i][1] = 0.0f; - } - } -} - -/* Calculates the moving HRIR target coefficients, target delays, and - * stepping values for the given polar elevation and azimuth in radians. - * Linear interpolation is used to increase the apparent resolution of the - * HRIR data set. The coefficients are also normalized and attenuated by the - * specified gain. Stepping resolution and count is determined using the - * given delta factor between 0.0 and 1.0. - */ -ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep) -{ - ALuint evidx[2], lidx[4], ridx[4]; - ALfloat mu[3], blend[4]; - ALfloat left, right; - ALfloat step; - ALuint i; - - /* Claculate elevation indices and interpolation factor. */ - CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]); - - for(i = 0;i < 2;i++) - { - ALuint azcount = Hrtf->azCount[evidx[i]]; - ALuint evoffset = Hrtf->evOffset[evidx[i]]; - ALuint azidx[2]; - - /* Calculate azimuth indices and interpolation factor for this elevation. */ - CalcAzIndices(azcount, azimuth, azidx, &mu[i]); - - /* Calculate a set of linear HRIR indices for left and right channels. */ - lidx[i*2 + 0] = evoffset + azidx[0]; - lidx[i*2 + 1] = evoffset + azidx[1]; - ridx[i*2 + 0] = evoffset + ((azcount-azidx[0]) % azcount); - ridx[i*2 + 1] = evoffset + ((azcount-azidx[1]) % azcount); - } - - // Calculate the stepping parameters. - delta = maxf(floorf(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f); - step = 1.0f / delta; - - /* Calculate 4 blending weights for 2D bilinear interpolation. */ - blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]); - blend[1] = ( mu[0]) * (1.0f-mu[2]); - blend[2] = (1.0f-mu[1]) * ( mu[2]); - blend[3] = ( mu[1]) * ( mu[2]); - - /* Calculate the HRIR delays using linear interpolation. Then calculate - * the delay stepping values using the target and previous running - * delays. - */ - left = (ALfloat)(delays[0] - (delayStep[0] * counter)); - right = (ALfloat)(delays[1] - (delayStep[1] * counter)); - - delays[0] = fastf2u((Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + - Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - delays[1] = fastf2u((Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + - Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - - delayStep[0] = fastf2i(step * (delays[0] - left)); - delayStep[1] = fastf2i(step * (delays[1] - right)); - - /* Calculate the sample offsets for the HRIR indices. */ - lidx[0] *= Hrtf->irSize; - lidx[1] *= Hrtf->irSize; - lidx[2] *= Hrtf->irSize; - lidx[3] *= Hrtf->irSize; - ridx[0] *= Hrtf->irSize; - ridx[1] *= Hrtf->irSize; - ridx[2] *= Hrtf->irSize; - ridx[3] *= Hrtf->irSize; - - /* Calculate the normalized and attenuated target HRIR coefficients using - * linear interpolation when there is enough gain to warrant it. Zero - * the target coefficients if gain is too low. Then calculate the - * coefficient stepping values using the target and previous running - * coefficients. - */ - if(gain > 0.0001f) - { - ALfloat c; - - gain *= 1.0f/32767.0f; - - i = 0; - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(PassthruCoeff, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(PassthruCoeff, c, dirfact) * gain; - - coeffStep[i][0] = step * (coeffs[i][0] - left); - coeffStep[i][1] = step * (coeffs[i][1] - right); - - for(i = 1;i < Hrtf->irSize;i++) - { - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(0.0f, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(0.0f, c, dirfact) * gain; - - coeffStep[i][0] = step * (coeffs[i][0] - left); - coeffStep[i][1] = step * (coeffs[i][1] - right); - } - } - else - { - for(i = 0;i < Hrtf->irSize;i++) - { - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - coeffs[i][0] = 0.0f; - coeffs[i][1] = 0.0f; - - coeffStep[i][0] = step * -left; - coeffStep[i][1] = step * -right; - } - } - - /* The stepping count is the number of samples necessary for the HRIR to - * complete its transition. The mixer will only apply stepping for this - * many samples. - */ - return fastf2u(delta); } static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate) { - const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; + const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1; struct Hrtf *Hrtf = NULL; ALboolean failed = AL_FALSE; ALuint rate = 0, irCount = 0; @@ -518,7 +320,7 @@ static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate) static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate) { - const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; + const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1; struct Hrtf *Hrtf = NULL; ALboolean failed = AL_FALSE; ALuint rate = 0, irCount = 0; @@ -21,8 +21,6 @@ ALCboolean FindHrtfFormat(enum DevFmtChannels *chans, ALCuint *srate); void FreeHrtfs(void); ALuint GetHrtfIrSize(const struct Hrtf *Hrtf); -ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]); -void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays); -ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep); +void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat (*coeffs)[2], ALuint *delays); #endif /* ALC_HRTF_H */ diff --git a/Alc/midi/fluidsynth.c b/Alc/midi/fluidsynth.c index bf774ab1..d08d4fb5 100644 --- a/Alc/midi/fluidsynth.c +++ b/Alc/midi/fluidsynth.c @@ -853,8 +853,8 @@ static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict return; if(state != AL_PLAYING) { - fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[FrontLeft], 0, 1, - DryBuffer[FrontRight], 0, 1); + fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[0], 0, 1, + DryBuffer[1], 0, 1); return; } @@ -882,8 +882,8 @@ static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict if(tonext > 0) { ALuint todo = minu(tonext, SamplesToDo-total); - fluid_synth_write_float(self->Synth, todo, DryBuffer[FrontLeft], total, 1, - DryBuffer[FrontRight], total, 1); + fluid_synth_write_float(self->Synth, todo, DryBuffer[0], total, 1, + DryBuffer[1], total, 1); total += todo; tonext -= todo; } diff --git a/Alc/mixer.c b/Alc/mixer.c index 5927bb7b..7a4d455d 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -41,20 +41,6 @@ extern inline void InitiatePositionArrays(ALuint frac, ALuint increment, ALuint *frac_arr, ALuint *pos_arr, ALuint size); -static inline HrtfMixerFunc SelectHrtfMixer(void) -{ -#ifdef HAVE_SSE - if((CPUCapFlags&CPU_CAP_SSE)) - return MixHrtf_SSE; -#endif -#ifdef HAVE_NEON - if((CPUCapFlags&CPU_CAP_NEON)) - return MixHrtf_Neon; -#endif - - return MixHrtf_C; -} - static inline MixerFunc SelectMixer(void) { #ifdef HAVE_SSE @@ -179,7 +165,6 @@ static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) { MixerFunc Mix; - HrtfMixerFunc HrtfMix; ResamplerFunc Resample; ALbufferlistitem *BufferListItem; ALuint DataPosInt, DataPosFrac; @@ -218,7 +203,6 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } Mix = SelectMixer(); - HrtfMix = SelectHrtfMixer(); Resample = ((increment == FRACTIONONE && DataPosFrac == 0) ? Resample_copy32_C : SelectResampler(Resampler)); @@ -431,13 +415,8 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam Device->FilteredData, ResampledData, DstBufferSize, parms->Filters[chan].ActiveType ); - if(!voice->IsHrtf) - Mix(samples, Device->NumChannels, parms->OutBuffer, parms->Mix.Gains[chan], - parms->Counter, OutPos, DstBufferSize); - else - HrtfMix(parms->OutBuffer, samples, parms->Counter, voice->Offset, - OutPos, parms->Mix.Hrtf.IrSize, &parms->Mix.Hrtf.Params[chan], - &parms->Mix.Hrtf.State[chan], DstBufferSize); + Mix(samples, Device->NumChannels, parms->OutBuffer, parms->Mix.Gains[chan], + parms->Counter, OutPos, DstBufferSize); } /* Only the first channel for B-Format buffers (W channel) goes to diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c index 0fdcc087..caedd339 100644 --- a/Alc/mixer_c.c +++ b/Alc/mixer_c.c @@ -59,23 +59,6 @@ void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const } -static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], - const ALuint IrSize, - ALfloat (*restrict Coeffs)[2], - const ALfloat (*restrict CoeffStep)[2], - ALfloat left, ALfloat right) -{ - ALuint c; - for(c = 0;c < IrSize;c++) - { - const ALuint off = (Offset+c)&HRIR_MASK; - Values[off][0] += Coeffs[c][0] * left; - Values[off][1] += Coeffs[c][1] * right; - Coeffs[c][0] += CoeffStep[c][0]; - Coeffs[c][1] += CoeffStep[c][1]; - } -} - static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, ALfloat (*restrict Coeffs)[2], diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h index c1500ed2..62dad9dc 100644 --- a/Alc/mixer_defs.h +++ b/Alc/mixer_defs.h @@ -20,17 +20,15 @@ const ALfloat *Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increm /* C mixers */ void MixHrtf_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, - ALuint BufferSize); + ALuint Offset, const ALuint IrSize, const struct HrtfParams *hrtfparams, + struct HrtfState *hrtfstate, ALuint BufferSize); void Mix_C(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); /* SSE mixers */ void MixHrtf_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, - ALuint BufferSize); + ALuint Offset, const ALuint IrSize, const struct HrtfParams *hrtfparams, + struct HrtfState *hrtfstate, ALuint BufferSize); void Mix_SSE(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); @@ -56,9 +54,8 @@ const ALfloat *Resample_lerp32_SSE41(const ALfloat *src, ALuint frac, ALuint inc /* Neon mixers */ void MixHrtf_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, - ALuint BufferSize); + ALuint Offset, const ALuint IrSize, const struct HrtfParams *hrtfparams, + struct HrtfState *hrtfstate, ALuint BufferSize); void Mix_Neon(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); diff --git a/Alc/mixer_inc.c b/Alc/mixer_inc.c index ab6f32c5..46ccec7d 100644 --- a/Alc/mixer_inc.c +++ b/Alc/mixer_inc.c @@ -14,11 +14,6 @@ #define MixHrtf MERGE(MixHrtf_,SUFFIX) -static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], - const ALuint irSize, - ALfloat (*restrict Coeffs)[2], - const ALfloat (*restrict CoeffStep)[2], - ALfloat left, ALfloat right); static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint irSize, ALfloat (*restrict Coeffs)[2], @@ -26,7 +21,7 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], void MixHrtf(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, + ALuint Offset, const ALuint IrSize, const HrtfParams *hrtfparams, HrtfState *hrtfstate, ALuint BufferSize) { alignas(16) ALfloat Coeffs[HRIR_LENGTH][2]; @@ -37,52 +32,25 @@ void MixHrtf(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, for(c = 0;c < IrSize;c++) { - Coeffs[c][0] = hrtfparams->Coeffs[c][0] - (hrtfparams->CoeffStep[c][0]*Counter); - Coeffs[c][1] = hrtfparams->Coeffs[c][1] - (hrtfparams->CoeffStep[c][1]*Counter); + Coeffs[c][0] = hrtfparams->Coeffs[c][0]; + Coeffs[c][1] = hrtfparams->Coeffs[c][1]; } - Delay[0] = hrtfparams->Delay[0] - (hrtfparams->DelayStep[0]*Counter); - Delay[1] = hrtfparams->Delay[1] - (hrtfparams->DelayStep[1]*Counter); + Delay[0] = hrtfparams->Delay[0]; + Delay[1] = hrtfparams->Delay[1]; - for(pos = 0;pos < BufferSize && pos < Counter;pos++) + for(pos = 0;pos < BufferSize;pos++) { - hrtfstate->History[Offset&SRC_HISTORY_MASK] = data[pos]; - left = lerp(hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], - hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], - (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); - right = lerp(hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], - hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], - (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); - - Delay[0] += hrtfparams->DelayStep[0]; - Delay[1] += hrtfparams->DelayStep[1]; - - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; - Offset++; - - ApplyCoeffsStep(Offset, hrtfstate->Values, IrSize, Coeffs, hrtfparams->CoeffStep, left, right); - OutBuffer[FrontLeft][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][0]; - OutBuffer[FrontRight][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][1]; - OutPos++; - } - - Delay[0] >>= HRTFDELAY_BITS; - Delay[1] >>= HRTFDELAY_BITS; - for(;pos < BufferSize;pos++) - { - hrtfstate->History[Offset&SRC_HISTORY_MASK] = data[pos]; - left = hrtfstate->History[(Offset-Delay[0])&SRC_HISTORY_MASK]; - right = hrtfstate->History[(Offset-Delay[1])&SRC_HISTORY_MASK]; + hrtfstate->History[Offset&HRTF_HISTORY_MASK] = data[pos]; + left = hrtfstate->History[(Offset-Delay[0])&HRTF_HISTORY_MASK]; + right = hrtfstate->History[(Offset-Delay[1])&HRTF_HISTORY_MASK]; hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; Offset++; ApplyCoeffs(Offset, hrtfstate->Values, IrSize, Coeffs, left, right); - OutBuffer[FrontLeft][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][0]; - OutBuffer[FrontRight][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][1]; - - OutPos++; + OutBuffer[0][pos] += hrtfstate->Values[Offset&HRIR_MASK][0]; + OutBuffer[1][pos] += hrtfstate->Values[Offset&HRIR_MASK][1]; } } diff --git a/Alc/mixer_neon.c b/Alc/mixer_neon.c index 8ce17644..413bd627 100644 --- a/Alc/mixer_neon.c +++ b/Alc/mixer_neon.c @@ -9,38 +9,6 @@ #include "hrtf.h" -static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], - const ALuint IrSize, - ALfloat (*restrict Coeffs)[2], - const ALfloat (*restrict CoeffStep)[2], - ALfloat left, ALfloat right) -{ - ALuint c; - float32x4_t leftright4; - { - float32x2_t leftright2 = vdup_n_f32(0.0); - leftright2 = vset_lane_f32(left, leftright2, 0); - leftright2 = vset_lane_f32(right, leftright2, 1); - leftright4 = vcombine_f32(leftright2, leftright2); - } - for(c = 0;c < IrSize;c += 2) - { - const ALuint o0 = (Offset+c)&HRIR_MASK; - const ALuint o1 = (o0+1)&HRIR_MASK; - float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]), - vld1_f32((float32_t*)&Values[o1][0])); - float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]); - float32x4_t deltas = vld1q_f32(&CoeffStep[c][0]); - - vals = vmlaq_f32(vals, coefs, leftright4); - coefs = vaddq_f32(coefs, deltas); - - vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals)); - vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals)); - vst1q_f32(&Coeffs[c][0], coefs); - } -} - static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, ALfloat (*restrict Coeffs)[2], diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c index d86cf749..d0dca40e 100644 --- a/Alc/mixer_sse.c +++ b/Alc/mixer_sse.c @@ -19,68 +19,6 @@ #include "mixer_defs.h" -static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], - const ALuint IrSize, - ALfloat (*restrict Coeffs)[2], - const ALfloat (*restrict CoeffStep)[2], - ALfloat left, ALfloat right) -{ - const __m128 lrlr = _mm_setr_ps(left, right, left, right); - __m128 coeffs, deltas, imp0, imp1; - __m128 vals = _mm_setzero_ps(); - ALuint i; - - if((Offset&1)) - { - const ALuint o0 = Offset&HRIR_MASK; - const ALuint o1 = (Offset+IrSize-1)&HRIR_MASK; - - coeffs = _mm_load_ps(&Coeffs[0][0]); - deltas = _mm_load_ps(&CoeffStep[0][0]); - vals = _mm_loadl_pi(vals, (__m64*)&Values[o0][0]); - imp0 = _mm_mul_ps(lrlr, coeffs); - coeffs = _mm_add_ps(coeffs, deltas); - vals = _mm_add_ps(imp0, vals); - _mm_store_ps(&Coeffs[0][0], coeffs); - _mm_storel_pi((__m64*)&Values[o0][0], vals); - for(i = 1;i < IrSize-1;i += 2) - { - const ALuint o2 = (Offset+i)&HRIR_MASK; - - coeffs = _mm_load_ps(&Coeffs[i+1][0]); - deltas = _mm_load_ps(&CoeffStep[i+1][0]); - vals = _mm_load_ps(&Values[o2][0]); - imp1 = _mm_mul_ps(lrlr, coeffs); - coeffs = _mm_add_ps(coeffs, deltas); - imp0 = _mm_shuffle_ps(imp0, imp1, _MM_SHUFFLE(1, 0, 3, 2)); - vals = _mm_add_ps(imp0, vals); - _mm_store_ps(&Coeffs[i+1][0], coeffs); - _mm_store_ps(&Values[o2][0], vals); - imp0 = imp1; - } - vals = _mm_loadl_pi(vals, (__m64*)&Values[o1][0]); - imp0 = _mm_movehl_ps(imp0, imp0); - vals = _mm_add_ps(imp0, vals); - _mm_storel_pi((__m64*)&Values[o1][0], vals); - } - else - { - for(i = 0;i < IrSize;i += 2) - { - const ALuint o = (Offset + i)&HRIR_MASK; - - coeffs = _mm_load_ps(&Coeffs[i][0]); - deltas = _mm_load_ps(&CoeffStep[i][0]); - vals = _mm_load_ps(&Values[o][0]); - imp0 = _mm_mul_ps(lrlr, coeffs); - coeffs = _mm_add_ps(coeffs, deltas); - vals = _mm_add_ps(imp0, vals); - _mm_store_ps(&Coeffs[i][0], coeffs); - _mm_store_ps(&Values[o][0], vals); - } - } -} - static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, ALfloat (*restrict Coeffs)[2], diff --git a/Alc/panning.c b/Alc/panning.c index f3305233..64be6f4b 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -124,6 +124,18 @@ DECL_CONST static inline const char *GetLabelFromChannel(enum Channel channel) case BackCenter: return "back-center"; case SideLeft: return "side-left"; case SideRight: return "side-right"; + + case TopCenter: return "top-center"; + case BottomCenter: return "bottom-center"; + case TopFrontLeft: return "top-front-left"; + case TopFrontRight: return "top-front-right"; + case TopBackLeft: return "top-back-left"; + case TopBackRight: return "top-back-right"; + case BottomFrontLeft: return "bottom-front-left"; + case BottomFrontRight: return "bottom-front-right"; + case BottomBackLeft: return "bottom-back-left"; + case BottomBackRight: return "bottom-back-right"; + case InvalidChannel: break; } return "(unknown)"; @@ -322,6 +334,21 @@ ALvoid aluInitPanning(ALCdevice *device) { BackRight, { { 0.224752f, -0.295009f, -0.170325f, 0.0f, 0.0f, 0.0f, 0.0f, 0.105349f, 0.182473f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000000f, -0.065799f }, { 0.224752f, -0.225790f, -0.130361f, 0.0f } } }, { SideLeft, { { 0.224739f, 0.000002f, 0.340644f, 0.0f, 0.0f, 0.0f, 0.0f, -0.210697f, 0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000000f, -0.065795f }, { 0.224739f, 0.000000f, 0.260717f, 0.0f } } }, { SideRight, { { 0.224739f, 0.000002f, -0.340644f, 0.0f, 0.0f, 0.0f, 0.0f, -0.210697f, -0.000002f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000000f, 0.065795f }, { 0.224739f, 0.000000f, -0.260717f, 0.0f } } }, + }, CubeDiamond[14] = { + { SideLeft, { { 0.130137f, -0.000013f, 0.207620f, 0.000001f, -0.081895f, 0.000001f, 0.000002f, -0.144357f, -0.000015f, -0.000002f, 0.000001f, -0.032339f, -0.000000f, 0.000001f, 0.000005f, -0.057583f }, { 0.130137f, -0.000009f, 0.139199f, 0.000001f } } }, + { FrontCenter, { { 0.130131f, 0.207613f, -0.000007f, 0.000001f, -0.081898f, 0.000001f, -0.000000f, 0.144354f, -0.000010f, -0.000002f, -0.032343f, 0.000006f, -0.000000f, -0.000001f, 0.057583f, -0.000004f }, { 0.130131f, 0.139195f, -0.000005f, 0.000001f } } }, + { SideRight, { { 0.130140f, 0.000001f, -0.207624f, -0.000001f, -0.081900f, 0.000005f, 0.000001f, -0.144357f, -0.000002f, 0.000002f, -0.000004f, 0.032342f, -0.000000f, -0.000005f, -0.000002f, 0.057580f }, { 0.130140f, 0.000000f, -0.139202f, -0.000000f } } }, + { BackCenter, { { 0.130142f, -0.207624f, 0.000006f, -0.000010f, -0.081897f, 0.000011f, 0.000005f, 0.144354f, -0.000006f, 0.000004f, 0.032340f, 0.000000f, -0.000002f, -0.000005f, -0.057579f, 0.000003f }, { 0.130142f, -0.139202f, 0.000004f, -0.000007f } } }, + { TopCenter, { { 0.072579f, 0.000006f, 0.000001f, 0.123524f, 0.126630f, 0.000008f, 0.000001f, -0.000002f, 0.000001f, 0.070290f, 0.000005f, 0.000001f, -0.000002f, 0.000001f, -0.000001f, 0.000002f }, { 0.072579f, 0.000004f, 0.000001f, 0.082817f } } }, + { BottomCenter, { { 0.072577f, -0.000008f, -0.000004f, -0.123522f, 0.126628f, 0.000012f, 0.000005f, -0.000001f, 0.000002f, -0.070291f, -0.000008f, -0.000002f, 0.000001f, -0.000002f, 0.000000f, -0.000001f }, { 0.072577f, -0.000006f, -0.000003f, -0.082815f } } }, + { TopFrontLeft, { { 0.176238f, 0.156939f, 0.156950f, 0.149964f, 0.006362f, 0.101960f, 0.101968f, -0.000003f, 0.117690f, -0.020696f, 0.018718f, 0.018723f, 0.000002f, 0.038069f, -0.025485f, 0.025484f }, { 0.176238f, 0.105220f, 0.105227f, 0.100544f } } }, + { TopFrontRight, { { 0.176240f, 0.156940f, -0.156956f, 0.149960f, 0.006356f, 0.101955f, -0.101970f, -0.000007f, -0.117691f, -0.020700f, 0.018719f, -0.018722f, -0.000003f, -0.038066f, -0.025485f, -0.025485f }, { 0.176240f, 0.105220f, -0.105231f, 0.100541f } } }, + { TopBackLeft, { { 0.176245f, -0.156957f, 0.156942f, 0.149971f, 0.006355f, -0.101977f, 0.101961f, 0.000003f, -0.117684f, -0.020701f, -0.018724f, 0.018716f, 0.000001f, -0.038069f, 0.025482f, 0.025479f }, { 0.176245f, -0.105232f, 0.105222f, 0.100548f } } }, + { TopBackRight, { { 0.176238f, -0.156944f, -0.156942f, 0.149972f, 0.006363f, -0.101976f, -0.101964f, -0.000005f, 0.117687f, -0.020701f, -0.018726f, -0.018716f, 0.000000f, 0.038072f, 0.025486f, -0.025481f }, { 0.176238f, -0.105224f, -0.105222f, 0.100549f } } }, + { BottomFrontLeft, { { 0.176248f, 0.156943f, 0.156950f, -0.149981f, 0.006371f, -0.101969f, -0.101967f, -0.000008f, 0.117685f, 0.020695f, 0.018723f, 0.018718f, 0.000000f, -0.038067f, -0.025486f, 0.025479f }, { 0.176248f, 0.105223f, 0.105227f, -0.100555f } } }, + { BottomFrontRight, { { 0.176236f, 0.156947f, -0.156945f, -0.149961f, 0.006353f, -0.101971f, 0.101964f, -0.000002f, -0.117689f, 0.020704f, 0.018723f, -0.018718f, -0.000001f, 0.038071f, -0.025484f, -0.025482f }, { 0.176236f, 0.105225f, -0.105224f, -0.100542f } } }, + { BottomBackLeft, { { 0.176236f, -0.156936f, 0.156952f, -0.149964f, 0.006358f, 0.101962f, -0.101976f, -0.000005f, -0.117687f, 0.020707f, -0.018720f, 0.018725f, 0.000001f, 0.038071f, 0.025483f, 0.025485f }, { 0.176236f, -0.105218f, 0.105229f, -0.100543f } } }, + { BottomBackRight, { { 0.176256f, -0.156956f, -0.156954f, -0.149974f, 0.006366f, 0.101960f, 0.101964f, 0.000003f, 0.117692f, 0.020690f, -0.018718f, -0.018722f, 0.000001f, -0.038064f, 0.025483f, -0.025484f }, { 0.176256f, -0.105232f, -0.105230f, -0.100550f } } }, }; const ChannelMap *chanmap = NULL; size_t count = 0; @@ -329,6 +356,43 @@ ALvoid aluInitPanning(ALCdevice *device) memset(device->Channel, 0, sizeof(device->Channel)); device->NumChannels = 0; + if(device->Hrtf) + { + static const struct { + enum Channel channel; + ALfloat elevation; + ALfloat angle; + } VirtualChans[14] = { + { FrontCenter, DEG2RAD( 0.0f), DEG2RAD( 0.0f) }, + { BackCenter, DEG2RAD( 0.0f), DEG2RAD(-180.0f) }, + { SideLeft, DEG2RAD( 0.0f), DEG2RAD( -90.0f) }, + { SideRight, DEG2RAD( 0.0f), DEG2RAD( 90.0f) }, + { TopFrontLeft, DEG2RAD( 45.0f), DEG2RAD( -45.0f) }, + { TopFrontRight, DEG2RAD( 45.0f), DEG2RAD( 45.0f) }, + { TopBackLeft, DEG2RAD( 45.0f), DEG2RAD(-135.0f) }, + { TopBackRight, DEG2RAD( 45.0f), DEG2RAD( 135.0f) }, + { BottomFrontLeft, DEG2RAD(-45.0f), DEG2RAD( -45.0f) }, + { BottomFrontRight, DEG2RAD(-45.0f), DEG2RAD( 45.0f) }, + { BottomBackLeft, DEG2RAD(-45.0f), DEG2RAD(-135.0f) }, + { BottomBackRight, DEG2RAD(-45.0f), DEG2RAD( 135.0f) }, + { TopCenter, DEG2RAD( 90.0f), DEG2RAD( 0.0f) }, + { BottomCenter, DEG2RAD(-90.0f), DEG2RAD( 0.0f) }, + }; + ALuint i; + + count = COUNTOF(CubeDiamond); + chanmap = CubeDiamond; + + for(i = 0;i < count;i++) + device->ChannelName[i] = VirtualChans[i].channel; + SetChannelMap(device, chanmap, count); + for(i = 0;i < count;i++) + GetLerpedHrtfCoeffs(device->Hrtf, VirtualChans[i].elevation, VirtualChans[i].angle, + device->Hrtf_Params[i].Coeffs, device->Hrtf_Params[i].Delay); + + return; + } + if(LoadChannelSetup(device)) return; |