aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorRaulshc <[email protected]>2018-05-31 14:17:20 +0200
committerGitHub <[email protected]>2018-05-31 14:17:20 +0200
commit5233c4aa21d01f8df3decd9b7c5746d8539094fd (patch)
treef19535db9bfafe797e3ca899fcdc86261673f1d8 /Alc
parentcd2fd126c4024f43730a7c857fca223b35fe0a5b (diff)
parent0b7f35b28922e2250f06d1aee1ebb60bfecf91d6 (diff)
Merge from kcat/master
Update git repository
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c15
-rw-r--r--Alc/ALu.c70
-rw-r--r--Alc/bformatdec.c8
-rw-r--r--Alc/effects/fshifter.c329
-rw-r--r--Alc/effects/modulator.c16
-rw-r--r--Alc/hrtf.c6
-rw-r--r--Alc/hrtf.h6
-rw-r--r--Alc/inprogext.h8
-rw-r--r--Alc/mixer/mixer_neon.c12
-rw-r--r--Alc/mixer/mixer_sse.c12
-rw-r--r--Alc/panning.c1
11 files changed, 403 insertions, 80 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 597cc890..1858c29b 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -550,8 +550,8 @@ static const struct {
DECL(AL_EFFECT_ECHO),
DECL(AL_EFFECT_FLANGER),
DECL(AL_EFFECT_PITCH_SHIFTER),
-#if 0
DECL(AL_EFFECT_FREQUENCY_SHIFTER),
+#if 0
DECL(AL_EFFECT_VOCAL_MORPHER),
#endif
DECL(AL_EFFECT_RING_MODULATOR),
@@ -632,6 +632,10 @@ static const struct {
DECL(AL_FLANGER_FEEDBACK),
DECL(AL_FLANGER_DELAY),
+ DECL(AL_FREQUENCY_SHIFTER_FREQUENCY),
+ DECL(AL_FREQUENCY_SHIFTER_LEFT_DIRECTION),
+ DECL(AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION),
+
DECL(AL_RING_MODULATOR_FREQUENCY),
DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
DECL(AL_RING_MODULATOR_WAVEFORM),
@@ -2213,9 +2217,12 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
break;
}
}
- else if(depth > 24)
- depth = 24;
- device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
+
+ if(depth > 0)
+ {
+ depth = clampi(depth, 2, 20);
+ device->DitherDepth = powf(2.0f, (ALfloat)(depth-1));
+ }
}
if(!(device->DitherDepth > 0.0f))
TRACE("Dithering disabled\n");
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 9d7fcdd5..dc24755d 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -145,16 +145,6 @@ static inline HrtfDirectMixerFunc SelectHrtfMixer(void)
}
-/* Prior to VS2013, MSVC lacks the round() family of functions. */
-#if defined(_MSC_VER) && _MSC_VER < 1800
-static float roundf(float val)
-{
- if(val < 0.0f)
- return ceilf(val-0.5f);
- return floorf(val+0.5f);
-}
-#endif
-
/* This RNG method was created based on the math found in opusdec. It's quick,
* and starting with a seed value of 22222, is suitable for generating
* whitenoise.
@@ -342,9 +332,7 @@ void aluSelectPostProcess(ALCdevice *device)
}
-/* Prepares the interpolator for a given rate (determined by increment). A
- * result of AL_FALSE indicates that the filter output will completely cut
- * the input signal.
+/* Prepares the interpolator for a given rate (determined by increment).
*
* With a bit of work, and a trade of memory for CPU cost, this could be
* modified for use with an interpolated increment for buttery-smooth pitch
@@ -1622,7 +1610,7 @@ static void ApplyDistanceComp(ALfloat (*restrict Samples)[BUFFERSIZE], DistanceC
continue;
}
- if(SamplesToDo >= base)
+ if(LIKELY(SamplesToDo >= base))
{
for(i = 0;i < base;i++)
Values[i] = distbuf[i];
@@ -1650,6 +1638,9 @@ static void ApplyDither(ALfloat (*restrict Samples)[BUFFERSIZE], ALuint *dither_
ALuint seed = *dither_seed;
ALsizei c, i;
+ ASSUME(numchans > 0);
+ ASSUME(SamplesToDo > 0);
+
/* Dithering. Step 1, generate whitenoise (uniform distribution of random
* values between -1 and +1). Step 2 is to add the noise to the samples,
* before rounding and after scaling up to the desired quantization depth.
@@ -1674,9 +1665,9 @@ static inline ALfloat Conv_ALfloat(ALfloat val)
{ return val; }
static inline ALint Conv_ALint(ALfloat val)
{
- /* Floats have a 23-bit mantissa. A bit of the exponent helps out along
- * with the sign bit, giving 25 bits. So [-16777216, +16777216] is the max
- * integer range normalized floats can be converted to before losing
+ /* Floats have a 23-bit mantissa. There is an implied 1 bit in the mantissa
+ * along with the sign bit, giving 25 bits total, so [-16777216, +16777216]
+ * is the max value a normalized float can be scaled to before losing
* precision.
*/
return fastf2i(clampf(val*16777216.0f, -16777216.0f, 16777215.0f))<<7;
@@ -1702,6 +1693,10 @@ static void Write##A(const ALfloat (*restrict InBuffer)[BUFFERSIZE], \
ALsizei numchans) \
{ \
ALsizei i, j; \
+ \
+ ASSUME(numchans > 0); \
+ ASSUME(SamplesToDo > 0); \
+ \
for(j = 0;j < numchans;j++) \
{ \
const ALfloat *restrict in = ASSUME_ALIGNED(InBuffer[j], 16); \
@@ -1833,27 +1828,16 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
switch(device->FmtType)
{
- case DevFmtByte:
- WriteI8(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
- case DevFmtUByte:
- WriteUI8(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
- case DevFmtShort:
- WriteI16(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
- case DevFmtUShort:
- WriteUI16(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
- case DevFmtInt:
- WriteI32(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
- case DevFmtUInt:
- WriteUI32(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
- case DevFmtFloat:
- WriteF32(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels);
- break;
+#define HANDLE_WRITE(T, S) case T: \
+ Write##S(Buffer, OutBuffer, SamplesDone, SamplesToDo, Channels); break;
+ HANDLE_WRITE(DevFmtByte, I8)
+ HANDLE_WRITE(DevFmtUByte, UI8)
+ HANDLE_WRITE(DevFmtShort, I16)
+ HANDLE_WRITE(DevFmtUShort, UI16)
+ HANDLE_WRITE(DevFmtInt, I32)
+ HANDLE_WRITE(DevFmtUInt, UI32)
+ HANDLE_WRITE(DevFmtFloat, F32)
+#undef HANDLE_WRITE
}
}
@@ -1883,17 +1867,7 @@ void aluHandleDisconnect(ALCdevice *device, const char *msg, ...)
va_end(args);
if(msglen < 0 || (size_t)msglen >= sizeof(evt.Message))
- {
evt.Message[sizeof(evt.Message)-1] = 0;
- msglen = (int)strlen(evt.Message);
- }
- if(msglen > 0)
- msg = evt.Message;
- else
- {
- msg = "<internal error constructing message>";
- msglen = (int)strlen(msg);
- }
ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
while(ctx)
diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c
index dcde7d70..58898083 100644
--- a/Alc/bformatdec.c
+++ b/Alc/bformatdec.c
@@ -450,11 +450,11 @@ void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat
{
for(j = 0;j < device->Dry.NumChannels;j++)
{
- ALfloat gain=0.0f;
+ ALdouble gain = 0.0;
for(k = 0;k < COUNTOF(Ambi3DDecoder);k++)
- gain += Ambi3DDecoder[k][i] * encgains[k][j];
- ambiup->Gains[i][j][HF_BAND] = gain * Ambi3DDecoderHFScale[i];
- ambiup->Gains[i][j][LF_BAND] = gain;
+ gain += (ALdouble)Ambi3DDecoder[k][i] * encgains[k][j];
+ ambiup->Gains[i][j][HF_BAND] = (ALfloat)(gain * Ambi3DDecoderHFScale[i]);
+ ambiup->Gains[i][j][LF_BAND] = (ALfloat)gain;
}
}
}
diff --git a/Alc/effects/fshifter.c b/Alc/effects/fshifter.c
new file mode 100644
index 00000000..5aa08453
--- /dev/null
+++ b/Alc/effects/fshifter.c
@@ -0,0 +1,329 @@
+/**
+ * OpenAL cross platform audio library
+ * Copyright (C) 2018 by Raul Herraiz.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Or go to http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "alMain.h"
+#include "alAuxEffectSlot.h"
+#include "alError.h"
+#include "alu.h"
+#include "filters/defs.h"
+
+#include "alcomplex.h"
+
+#define HIL_SIZE 1024
+#define OVERSAMP (1<<2)
+
+#define HIL_STEP (HIL_SIZE / OVERSAMP)
+#define FIFO_LATENCY (HIL_STEP * (OVERSAMP-1))
+
+
+typedef struct ALfshifterState {
+ DERIVE_FROM_TYPE(ALeffectState);
+
+ /* Effect parameters */
+ ALsizei count;
+ ALsizei PhaseStep;
+ ALsizei Phase;
+ ALdouble ld_sign;
+
+ /*Effects buffers*/
+ ALfloat InFIFO[HIL_SIZE];
+ ALcomplex OutFIFO[HIL_SIZE];
+ ALcomplex OutputAccum[HIL_SIZE];
+ ALcomplex Analytic[HIL_SIZE];
+ ALcomplex Outdata[BUFFERSIZE];
+
+ alignas(16) ALfloat BufferOut[BUFFERSIZE];
+
+ /* Effect gains for each output channel */
+ ALfloat CurrentGains[MAX_OUTPUT_CHANNELS];
+ ALfloat TargetGains[MAX_OUTPUT_CHANNELS];
+} ALfshifterState;
+
+static ALvoid ALfshifterState_Destruct(ALfshifterState *state);
+static ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *device);
+static ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props);
+static ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
+DECLARE_DEFAULT_ALLOCATORS(ALfshifterState)
+
+DEFINE_ALEFFECTSTATE_VTABLE(ALfshifterState);
+
+/* Define a Hann window, used to filter the HIL input and output. */
+alignas(16) static ALdouble HannWindow[HIL_SIZE];
+
+static void InitHannWindow(void)
+{
+ ALsizei i;
+
+ /* Create lookup table of the Hann window for the desired size, i.e. HIL_SIZE */
+ for(i = 0;i < HIL_SIZE>>1;i++)
+ {
+ ALdouble val = sin(M_PI * (ALdouble)i / (ALdouble)(HIL_SIZE-1));
+ HannWindow[i] = HannWindow[HIL_SIZE-1-i] = val * val;
+ }
+}
+
+static alonce_flag HannInitOnce = AL_ONCE_FLAG_INIT;
+
+static void ALfshifterState_Construct(ALfshifterState *state)
+{
+ ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
+ SET_VTABLE2(ALfshifterState, ALeffectState, state);
+
+ alcall_once(&HannInitOnce, InitHannWindow);
+}
+
+static ALvoid ALfshifterState_Destruct(ALfshifterState *state)
+{
+ ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
+}
+
+static ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *UNUSED(device))
+{
+ /* (Re-)initializing parameters and clear the buffers. */
+ state->count = FIFO_LATENCY;
+ state->PhaseStep = 0;
+ state->Phase = 0;
+ state->ld_sign = 1.0;
+
+ memset(state->InFIFO, 0, sizeof(state->InFIFO));
+ memset(state->OutFIFO, 0, sizeof(state->OutFIFO));
+ memset(state->OutputAccum, 0, sizeof(state->OutputAccum));
+ memset(state->Analytic, 0, sizeof(state->Analytic));
+
+ memset(state->CurrentGains, 0, sizeof(state->CurrentGains));
+ memset(state->TargetGains, 0, sizeof(state->TargetGains));
+
+ return AL_TRUE;
+}
+
+static ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props)
+{
+ const ALCdevice *device = context->Device;
+ ALfloat coeffs[MAX_AMBI_COEFFS];
+ ALfloat step;
+
+ step = props->Fshifter.Frequency / (ALfloat)device->Frequency;
+ state->PhaseStep = fastf2i(minf(step, 0.5f) * FRACTIONONE);
+
+ switch(props->Fshifter.LeftDirection)
+ {
+ case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN:
+ state->ld_sign = -1.0;
+ break;
+
+ case AL_FREQUENCY_SHIFTER_DIRECTION_UP:
+ state->ld_sign = 1.0;
+ break;
+
+ case AL_FREQUENCY_SHIFTER_DIRECTION_OFF:
+ state->Phase = 0;
+ state->PhaseStep = 0;
+ break;
+ }
+
+ CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs);
+ ComputeDryPanGains(&device->Dry, coeffs, slot->Params.Gain, state->TargetGains);
+}
+
+static ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
+{
+ static const ALcomplex complex_zero = { 0.0, 0.0 };
+ ALfloat *restrict BufferOut = state->BufferOut;
+ ALsizei j, k, base;
+
+ for(base = 0;base < SamplesToDo;)
+ {
+ ALsizei todo = mini(HIL_SIZE-state->count, SamplesToDo-base);
+
+ ASSUME(todo > 0);
+
+ /* Fill FIFO buffer with samples data */
+ k = state->count;
+ for(j = 0;j < todo;j++,k++)
+ {
+ state->InFIFO[k] = SamplesIn[0][base+j];
+ state->Outdata[base+j] = state->OutFIFO[k-FIFO_LATENCY];
+ }
+ state->count += todo;
+ base += todo;
+
+ /* Check whether FIFO buffer is filled */
+ if(state->count < HIL_SIZE) continue;
+
+ state->count = FIFO_LATENCY;
+
+ /* Real signal windowing and store in Analytic buffer */
+ for(k = 0;k < HIL_SIZE;k++)
+ {
+ state->Analytic[k].Real = state->InFIFO[k] * HannWindow[k];
+ state->Analytic[k].Imag = 0.0;
+ }
+
+ /* Processing signal by Discrete Hilbert Transform (analytical signal). */
+ complex_hilbert(state->Analytic, HIL_SIZE);
+
+ /* Windowing and add to output accumulator */
+ for(k = 0;k < HIL_SIZE;k++)
+ {
+ state->OutputAccum[k].Real += 2.0/OVERSAMP*HannWindow[k]*state->Analytic[k].Real;
+ state->OutputAccum[k].Imag += 2.0/OVERSAMP*HannWindow[k]*state->Analytic[k].Imag;
+ }
+
+ /* Shift accumulator, input & output FIFO */
+ for(k = 0;k < HIL_STEP;k++) state->OutFIFO[k] = state->OutputAccum[k];
+ for(j = 0;k < HIL_SIZE;k++,j++) state->OutputAccum[j] = state->OutputAccum[k];
+ for(;j < HIL_SIZE;j++) state->OutputAccum[j] = complex_zero;
+ for(k = 0;k < FIFO_LATENCY;k++)
+ state->InFIFO[k] = state->InFIFO[k+HIL_STEP];
+ }
+
+ /* Process frequency shifter using the analytic signal obtained. */
+ for(k = 0;k < SamplesToDo;k++)
+ {
+ ALdouble phase = state->Phase * ((1.0/FRACTIONONE) * 2.0*M_PI);
+ BufferOut[k] = (ALfloat)(state->Outdata[k].Real*cos(phase) +
+ state->Outdata[k].Imag*sin(phase)*state->ld_sign);
+
+ state->Phase += state->PhaseStep;
+ state->Phase &= FRACTIONMASK;
+ }
+
+ /* Now, mix the processed sound data to the output. */
+ MixSamples(BufferOut, NumChannels, SamplesOut, state->CurrentGains, state->TargetGains,
+ maxi(SamplesToDo, 512), 0, SamplesToDo);
+}
+
+typedef struct FshifterStateFactory {
+ DERIVE_FROM_TYPE(EffectStateFactory);
+} FshifterStateFactory;
+
+static ALeffectState *FshifterStateFactory_create(FshifterStateFactory *UNUSED(factory))
+{
+ ALfshifterState *state;
+
+ NEW_OBJ0(state, ALfshifterState)();
+ if(!state) return NULL;
+
+ return STATIC_CAST(ALeffectState, state);
+}
+
+DEFINE_EFFECTSTATEFACTORY_VTABLE(FshifterStateFactory);
+
+EffectStateFactory *FshifterStateFactory_getFactory(void)
+{
+ static FshifterStateFactory FshifterFactory = { { GET_VTABLE2(FshifterStateFactory, EffectStateFactory) } };
+
+ return STATIC_CAST(EffectStateFactory, &FshifterFactory);
+}
+
+void ALfshifter_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val)
+{
+ ALeffectProps *props = &effect->Props;
+ switch(param)
+ {
+ case AL_FREQUENCY_SHIFTER_FREQUENCY:
+ if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY))
+ SETERR_RETURN(context, AL_INVALID_VALUE,,"Frequency shifter frequency out of range");
+ props->Fshifter.Frequency = val;
+ break;
+
+ default:
+ alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x", param);
+ }
+}
+
+void ALfshifter_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals)
+{
+ ALfshifter_setParamf(effect, context, param, vals[0]);
+}
+
+void ALfshifter_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val)
+{
+ ALeffectProps *props = &effect->Props;
+ switch(param)
+ {
+ case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION:
+ if(!(val >= AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION && val <= AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION))
+ SETERR_RETURN(context, AL_INVALID_VALUE,,"Frequency shifter left direction out of range");
+ props->Fshifter.LeftDirection = val;
+ break;
+
+ case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION:
+ if(!(val >= AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION && val <= AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION))
+ SETERR_RETURN(context, AL_INVALID_VALUE,,"Frequency shifter right direction out of range");
+ props->Fshifter.RightDirection = val;
+ break;
+
+ default:
+ alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter integer property 0x%04x", param);
+ }
+}
+void ALfshifter_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals)
+{
+ ALfshifter_setParami(effect, context, param, vals[0]);
+}
+
+void ALfshifter_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val)
+{
+ const ALeffectProps *props = &effect->Props;
+ switch(param)
+ {
+ case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION:
+ *val = props->Fshifter.LeftDirection;
+ break;
+ case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION:
+ *val = props->Fshifter.RightDirection;
+ break;
+ default:
+ alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter integer property 0x%04x", param);
+ }
+}
+void ALfshifter_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals)
+{
+ ALfshifter_getParami(effect, context, param, vals);
+}
+
+void ALfshifter_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val)
+{
+
+ const ALeffectProps *props = &effect->Props;
+ switch(param)
+ {
+ case AL_FREQUENCY_SHIFTER_FREQUENCY:
+ *val = props->Fshifter.Frequency;
+ break;
+
+ default:
+ alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x", param);
+ }
+
+}
+
+void ALfshifter_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals)
+{
+ ALfshifter_getParamf(effect, context, param, vals);
+}
+
+DEFINE_ALEFFECT_VTABLE(ALfshifter);
diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c
index 7f1a2cad..7985f03e 100644
--- a/Alc/effects/modulator.c
+++ b/Alc/effects/modulator.c
@@ -40,8 +40,6 @@ typedef struct ALmodulatorState {
ALsizei index;
ALsizei step;
- alignas(16) ALfloat ModSamples[MAX_UPDATE_SAMPLES];
-
struct {
BiquadFilter Filter;
@@ -137,7 +135,8 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCcontext
else /*if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/
state->GetSamples = ModulateSquare;
- state->step = float2int(props->Modulator.Frequency*WAVEFORM_FRACONE/device->Frequency + 0.5f);
+ state->step = fastf2i(props->Modulator.Frequency / (ALfloat)device->Frequency *
+ WAVEFORM_FRACONE);
state->step = clampi(state->step, 1, WAVEFORM_FRACONE-1);
/* Custom filter coeffs, which match the old version instead of a low-shelf. */
@@ -161,13 +160,12 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCcontext
static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
{
- ALfloat *restrict modsamples = ASSUME_ALIGNED(state->ModSamples, 16);
const ALsizei step = state->step;
ALsizei base;
for(base = 0;base < SamplesToDo;)
{
- alignas(16) ALfloat temps[2][MAX_UPDATE_SAMPLES];
+ alignas(16) ALfloat modsamples[MAX_UPDATE_SAMPLES];
ALsizei td = mini(MAX_UPDATE_SAMPLES, SamplesToDo-base);
ALsizei c, i;
@@ -177,11 +175,13 @@ static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesT
for(c = 0;c < MAX_EFFECT_CHANNELS;c++)
{
- BiquadFilter_process(&state->Chans[c].Filter, temps[0], &SamplesIn[c][base], td);
+ alignas(16) ALfloat temps[MAX_UPDATE_SAMPLES];
+
+ BiquadFilter_process(&state->Chans[c].Filter, temps, &SamplesIn[c][base], td);
for(i = 0;i < td;i++)
- temps[1][i] = temps[0][i] * modsamples[i];
+ temps[i] *= modsamples[i];
- MixSamples(temps[1], NumChannels, SamplesOut, state->Chans[c].CurrentGains,
+ MixSamples(temps, NumChannels, SamplesOut, state->Chans[c].CurrentGains,
state->Chans[c].TargetGains, SamplesToDo-base, base, td);
}
diff --git a/Alc/hrtf.c b/Alc/hrtf.c
index 376c849f..ddbd3a28 100644
--- a/Alc/hrtf.c
+++ b/Alc/hrtf.c
@@ -202,13 +202,15 @@ void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, ALsizei N
#define NUM_BANDS 2
BandSplitter splitter;
ALdouble (*tmpres)[HRIR_LENGTH][2];
- ALsizei idx[HRTF_AMBI_MAX_CHANNELS];
+ ALsizei *restrict idx;
ALsizei min_delay = HRTF_HISTORY_LENGTH;
ALsizei max_delay = 0;
ALfloat temps[3][HRIR_LENGTH];
ALsizei max_length;
ALsizei i, c, b;
+ idx = al_calloc(DEF_ALIGN, AmbiCount*sizeof(*idx));
+
for(c = 0;c < AmbiCount;c++)
{
ALuint evidx, azidx;
@@ -312,6 +314,8 @@ void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, ALsizei N
}
al_free(tmpres);
tmpres = NULL;
+ al_free(idx);
+ idx = NULL;
if(NUM_BANDS == 1)
max_length = mini(max_delay-min_delay + Hrtf->irSize, HRIR_LENGTH);
diff --git a/Alc/hrtf.h b/Alc/hrtf.h
index aaffa904..ab68929b 100644
--- a/Alc/hrtf.h
+++ b/Alc/hrtf.h
@@ -9,12 +9,6 @@
#include "atomic.h"
-/* The maximum number of virtual speakers used to generate HRTF coefficients
- * for decoding B-Format.
- */
-#define HRTF_AMBI_MAX_CHANNELS 18
-
-
#define HRTF_HISTORY_BITS (6)
#define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
#define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
diff --git a/Alc/inprogext.h b/Alc/inprogext.h
index 619b604f..3025abe2 100644
--- a/Alc/inprogext.h
+++ b/Alc/inprogext.h
@@ -72,6 +72,14 @@ AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void **values);
#endif
#endif
+#ifndef AL_SOFT_buffer_layers
+#define AL_SOFT_buffer_layers
+typedef void (AL_APIENTRY*LPALSOURCEQUEUEBUFFERLAYERSSOFT)(ALuint src, ALsizei nb, const ALuint *buffers);
+#ifdef AL_ALEXT_PROTOTYPES
+AL_API void AL_APIENTRY alSourceQueueBufferLayersSOFT(ALuint src, ALsizei nb, const ALuint *buffers);
+#endif
+#endif
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/Alc/mixer/mixer_neon.c b/Alc/mixer/mixer_neon.c
index 0af977e6..9aa279a2 100644
--- a/Alc/mixer/mixer_neon.c
+++ b/Alc/mixer/mixer_neon.c
@@ -101,16 +101,20 @@ const ALfloat *Resample_bsinc_Neon(const InterpState *state,
// Apply the scale and phase interpolated filter.
r4 = vdupq_n_f32(0.0f);
{
+ const ALsizei count = m >> 2;
const float32x4_t pf4 = vdupq_n_f32(pf);
- for(j = 0;j < m;j+=4,fil++,scd++,phd++,spd++)
+
+ ASSUME(count > 0);
+
+ for(j = 0;j < count;j++)
{
/* f = ((fil + sf*scd) + pf*(phd + sf*spd)) */
const float32x4_t f4 = vmlaq_f32(
- vmlaq_f32(*fil, sf4, *scd),
- pf4, vmlaq_f32(*phd, sf4, *spd)
+ vmlaq_f32(fil[j], sf4, scd[j]),
+ pf4, vmlaq_f32(phd[j], sf4, spd[j])
);
/* r += f*src */
- r4 = vmlaq_f32(r4, f4, vld1q_f32(&src[j]));
+ r4 = vmlaq_f32(r4, f4, vld1q_f32(&src[j*4]));
}
}
r4 = vaddq_f32(r4, vcombine_f32(vrev64_f32(vget_high_f32(r4)),
diff --git a/Alc/mixer/mixer_sse.c b/Alc/mixer/mixer_sse.c
index 5b4208f9..d7d54993 100644
--- a/Alc/mixer/mixer_sse.c
+++ b/Alc/mixer/mixer_sse.c
@@ -45,17 +45,21 @@ const ALfloat *Resample_bsinc_SSE(const InterpState *state, const ALfloat *restr
// Apply the scale and phase interpolated filter.
r4 = _mm_setzero_ps();
{
+ const ALsizei count = m >> 2;
const __m128 pf4 = _mm_set1_ps(pf);
+
+ ASSUME(count > 0);
+
#define MLA4(x, y, z) _mm_add_ps(x, _mm_mul_ps(y, z))
- for(j = 0;j < m;j+=4,fil++,scd++,phd++,spd++)
+ for(j = 0;j < count;j++)
{
/* f = ((fil + sf*scd) + pf*(phd + sf*spd)) */
const __m128 f4 = MLA4(
- MLA4(*fil, sf4, *scd),
- pf4, MLA4(*phd, sf4, *spd)
+ MLA4(fil[j], sf4, scd[j]),
+ pf4, MLA4(phd[j], sf4, spd[j])
);
/* r += f*src */
- r4 = MLA4(r4, f4, _mm_loadu_ps(&src[j]));
+ r4 = MLA4(r4, f4, _mm_loadu_ps(&src[j*4]));
}
#undef MLA4
}
diff --git a/Alc/panning.c b/Alc/panning.c
index 4a7c592b..e4562387 100644
--- a/Alc/panning.c
+++ b/Alc/panning.c
@@ -884,7 +884,6 @@ static void InitHrtfPanning(ALCdevice *device)
static_assert(COUNTOF(AmbiPoints) == COUNTOF(AmbiMatrixFOA), "FOA Ambisonic HRTF mismatch");
static_assert(COUNTOF(AmbiPoints) == COUNTOF(AmbiMatrixHOA), "HOA Ambisonic HRTF mismatch");
- static_assert(COUNTOF(AmbiPoints) <= HRTF_AMBI_MAX_CHANNELS, "HRTF_AMBI_MAX_CHANNELS is too small");
if(device->AmbiUp)
{