aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
Diffstat (limited to 'alc')
-rw-r--r--alc/alu.cpp144
-rw-r--r--alc/alu.h9
-rw-r--r--alc/converter.cpp12
-rw-r--r--alc/mixvoice.cpp54
4 files changed, 108 insertions, 111 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 5df1c3a2..4e9bf9e0 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -147,6 +147,83 @@ inline HrtfDirectMixerFunc SelectHrtfMixer(void)
return MixDirectHrtf_<CTag>;
}
+
+inline void BsincPrepare(const ALuint increment, BsincState *state, const BSincTable *table)
+{
+ size_t si{BSINC_SCALE_COUNT - 1};
+ float sf{0.0f};
+
+ if(increment > FRACTIONONE)
+ {
+ sf = FRACTIONONE / static_cast<float>(increment);
+ sf = maxf(0.0f, (BSINC_SCALE_COUNT-1) * (sf-table->scaleBase) * table->scaleRange);
+ si = float2uint(sf);
+ /* The interpolation factor is fit to this diagonally-symmetric curve
+ * to reduce the transition ripple caused by interpolating different
+ * scales of the sinc function.
+ */
+ sf = 1.0f - std::cos(std::asin(sf - static_cast<float>(si)));
+ }
+
+ state->sf = sf;
+ state->m = table->m[si];
+ state->l = (state->m/2) - 1;
+ state->filter = table->Tab + table->filterOffset[si];
+}
+
+inline ResamplerFunc SelectResampler(Resampler resampler, ALuint increment)
+{
+ switch(resampler)
+ {
+ case Resampler::Point:
+ return Resample_<PointTag,CTag>;
+ case Resampler::Linear:
+#ifdef HAVE_NEON
+ if((CPUCapFlags&CPU_CAP_NEON))
+ return Resample_<LerpTag,NEONTag>;
+#endif
+#ifdef HAVE_SSE4_1
+ if((CPUCapFlags&CPU_CAP_SSE4_1))
+ return Resample_<LerpTag,SSE4Tag>;
+#endif
+#ifdef HAVE_SSE2
+ if((CPUCapFlags&CPU_CAP_SSE2))
+ return Resample_<LerpTag,SSE2Tag>;
+#endif
+ return Resample_<LerpTag,CTag>;
+ case Resampler::Cubic:
+ return Resample_<CubicTag,CTag>;
+ case Resampler::BSinc12:
+ case Resampler::BSinc24:
+ if(increment <= FRACTIONONE)
+ {
+ /* fall-through */
+ case Resampler::FastBSinc12:
+ case Resampler::FastBSinc24:
+#ifdef HAVE_NEON
+ if((CPUCapFlags&CPU_CAP_NEON))
+ return Resample_<FastBSincTag,NEONTag>;
+#endif
+#ifdef HAVE_SSE
+ if((CPUCapFlags&CPU_CAP_SSE))
+ return Resample_<FastBSincTag,SSETag>;
+#endif
+ return Resample_<FastBSincTag,CTag>;
+ }
+#ifdef HAVE_NEON
+ if((CPUCapFlags&CPU_CAP_NEON))
+ return Resample_<BSincTag,NEONTag>;
+#endif
+#ifdef HAVE_SSE
+ if((CPUCapFlags&CPU_CAP_SSE))
+ return Resample_<BSincTag,SSETag>;
+#endif
+ return Resample_<BSincTag,CTag>;
+ }
+
+ return Resample_<PointTag,CTag>;
+}
+
} // namespace
void aluInit(void)
@@ -155,6 +232,27 @@ void aluInit(void)
}
+ResamplerFunc PrepareResampler(Resampler resampler, ALuint increment, InterpState *state)
+{
+ switch(resampler)
+ {
+ case Resampler::Point:
+ case Resampler::Linear:
+ case Resampler::Cubic:
+ break;
+ case Resampler::FastBSinc12:
+ case Resampler::BSinc12:
+ BsincPrepare(increment, &state->bsinc, &bsinc12);
+ break;
+ case Resampler::FastBSinc24:
+ case Resampler::BSinc24:
+ BsincPrepare(increment, &state->bsinc, &bsinc24);
+ break;
+ }
+ return SelectResampler(resampler, increment);
+}
+
+
void ALCdevice::ProcessHrtf(const size_t SamplesToDo)
{
/* HRTF is stereo output only. */
@@ -196,36 +294,6 @@ void ALCdevice::ProcessBs2b(const size_t SamplesToDo)
}
-/* 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
- * changes.
- */
-void BsincPrepare(const ALuint increment, BsincState *state, const BSincTable *table)
-{
- size_t si{BSINC_SCALE_COUNT - 1};
- float sf{0.0f};
-
- if(increment > FRACTIONONE)
- {
- sf = FRACTIONONE / static_cast<float>(increment);
- sf = maxf(0.0f, (BSINC_SCALE_COUNT-1) * (sf-table->scaleBase) * table->scaleRange);
- si = float2uint(sf);
- /* The interpolation factor is fit to this diagonally-symmetric curve
- * to reduce the transition ripple caused by interpolating different
- * scales of the sinc function.
- */
- sf = 1.0f - std::cos(std::asin(sf - static_cast<float>(si)));
- }
-
- state->sf = sf;
- state->m = table->m[si];
- state->l = (state->m/2) - 1;
- state->filter = table->Tab + table->filterOffset[si];
-}
-
-
namespace {
/* This RNG method was created based on the math found in opusdec. It's quick,
@@ -943,15 +1011,11 @@ void CalcNonAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, cons
/* Calculate the stepping value */
const auto Pitch = static_cast<ALfloat>(voice->mFrequency) /
static_cast<ALfloat>(Device->Frequency) * props->Pitch;
- if(Pitch > static_cast<ALfloat>(MAX_PITCH))
+ if(Pitch > float{MAX_PITCH})
voice->mStep = MAX_PITCH<<FRACTIONBITS;
else
voice->mStep = maxu(fastf2u(Pitch * FRACTIONONE), 1);
- if(props->mResampler == Resampler::BSinc24 || props->mResampler == Resampler::FastBSinc24)
- BsincPrepare(voice->mStep, &voice->mResampleState.bsinc, &bsinc24);
- else if(props->mResampler == Resampler::BSinc12 || props->mResampler == Resampler::FastBSinc12)
- BsincPrepare(voice->mStep, &voice->mResampleState.bsinc, &bsinc12);
- voice->mResampler = SelectResampler(props->mResampler, voice->mStep);
+ voice->mResampler = PrepareResampler(props->mResampler, voice->mStep, &voice->mResampleState);
/* Calculate gains */
const ALlistener &Listener = ALContext->mListener;
@@ -1273,15 +1337,11 @@ void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const A
* fixed-point stepping value.
*/
Pitch *= static_cast<ALfloat>(voice->mFrequency)/static_cast<ALfloat>(Device->Frequency);
- if(Pitch > static_cast<ALfloat>(MAX_PITCH))
+ if(Pitch > float{MAX_PITCH})
voice->mStep = MAX_PITCH<<FRACTIONBITS;
else
voice->mStep = maxu(fastf2u(Pitch * FRACTIONONE), 1);
- if(props->mResampler == Resampler::BSinc24 || props->mResampler == Resampler::FastBSinc24)
- BsincPrepare(voice->mStep, &voice->mResampleState.bsinc, &bsinc24);
- else if(props->mResampler == Resampler::BSinc12 || props->mResampler == Resampler::FastBSinc12)
- BsincPrepare(voice->mStep, &voice->mResampleState.bsinc, &bsinc12);
- voice->mResampler = SelectResampler(props->mResampler, voice->mStep);
+ voice->mResampler = PrepareResampler(props->mResampler, voice->mStep, &voice->mResampleState);
ALfloat spread{0.0f};
if(props->Radius > Distance)
diff --git a/alc/alu.h b/alc/alu.h
index e2b25556..476e3ab9 100644
--- a/alc/alu.h
+++ b/alc/alu.h
@@ -85,11 +85,6 @@ union InterpState {
using ResamplerFunc = const ALfloat*(*)(const InterpState *state, const ALfloat *RESTRICT src,
ALuint frac, ALuint increment, const al::span<float> dst);
-void BsincPrepare(const ALuint increment, BsincState *state, const BSincTable *table);
-
-extern const BSincTable bsinc12;
-extern const BSincTable bsinc24;
-
enum {
AF_None = 0,
@@ -372,8 +367,6 @@ void aluInit(void);
void aluInitMixer(void);
-ResamplerFunc SelectResampler(Resampler resampler, ALuint increment);
-
/* aluInitRenderer
*
* Set up the appropriate panning method and mixing method given the device
@@ -383,6 +376,8 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, HrtfRequestMode hrtf_appr
void aluInitEffectPanning(ALeffectslot *slot, ALCdevice *device);
+ResamplerFunc PrepareResampler(Resampler resampler, ALuint increment, InterpState *state);
+
/**
* Calculates ambisonic encoder coefficients using the X, Y, and Z direction
* components, which must represent a normalized (unit length) vector, and the
diff --git a/alc/converter.cpp b/alc/converter.cpp
index aff1c353..0e7bd82f 100644
--- a/alc/converter.cpp
+++ b/alc/converter.cpp
@@ -10,6 +10,7 @@
#include "AL/al.h"
#include "albyte.h"
+#include "alu.h"
#include "fpu_modes.h"
#include "mixer/defs.h"
@@ -161,18 +162,13 @@ SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType,
/* Have to set the mixer FPU mode since that's what the resampler code expects. */
FPUCtl mixer_mode{};
auto step = static_cast<ALuint>(
- mind(srcRate*ALdouble{FRACTIONONE}/dstRate + 0.5, MAX_PITCH*FRACTIONONE));
+ mind(srcRate*double{FRACTIONONE}/dstRate + 0.5, MAX_PITCH*FRACTIONONE));
converter->mIncrement = maxu(step, 1);
if(converter->mIncrement == FRACTIONONE)
converter->mResample = Resample_<CopyTag,CTag>;
else
- {
- if(resampler == Resampler::BSinc24 || resampler == Resampler::FastBSinc24)
- BsincPrepare(converter->mIncrement, &converter->mState.bsinc, &bsinc24);
- else if(resampler == Resampler::BSinc12 || resampler == Resampler::FastBSinc12)
- BsincPrepare(converter->mIncrement, &converter->mState.bsinc, &bsinc12);
- converter->mResample = SelectResampler(resampler, converter->mIncrement);
- }
+ converter->mResample = PrepareResampler(resampler, converter->mIncrement,
+ &converter->mState);
return converter;
}
diff --git a/alc/mixvoice.cpp b/alc/mixvoice.cpp
index e9e0d8df..3e4c73a6 100644
--- a/alc/mixvoice.cpp
+++ b/alc/mixvoice.cpp
@@ -135,60 +135,6 @@ inline HrtfMixerBlendFunc SelectHrtfBlendMixer()
} // namespace
-ResamplerFunc SelectResampler(Resampler resampler, ALuint increment)
-{
- switch(resampler)
- {
- case Resampler::Point:
- return Resample_<PointTag,CTag>;
- case Resampler::Linear:
-#ifdef HAVE_NEON
- if((CPUCapFlags&CPU_CAP_NEON))
- return Resample_<LerpTag,NEONTag>;
-#endif
-#ifdef HAVE_SSE4_1
- if((CPUCapFlags&CPU_CAP_SSE4_1))
- return Resample_<LerpTag,SSE4Tag>;
-#endif
-#ifdef HAVE_SSE2
- if((CPUCapFlags&CPU_CAP_SSE2))
- return Resample_<LerpTag,SSE2Tag>;
-#endif
- return Resample_<LerpTag,CTag>;
- case Resampler::Cubic:
- return Resample_<CubicTag,CTag>;
- case Resampler::BSinc12:
- case Resampler::BSinc24:
- if(increment <= FRACTIONONE)
- {
- /* fall-through */
- case Resampler::FastBSinc12:
- case Resampler::FastBSinc24:
-#ifdef HAVE_NEON
- if((CPUCapFlags&CPU_CAP_NEON))
- return Resample_<FastBSincTag,NEONTag>;
-#endif
-#ifdef HAVE_SSE
- if((CPUCapFlags&CPU_CAP_SSE))
- return Resample_<FastBSincTag,SSETag>;
-#endif
- return Resample_<FastBSincTag,CTag>;
- }
-#ifdef HAVE_NEON
- if((CPUCapFlags&CPU_CAP_NEON))
- return Resample_<BSincTag,NEONTag>;
-#endif
-#ifdef HAVE_SSE
- if((CPUCapFlags&CPU_CAP_SSE))
- return Resample_<BSincTag,SSETag>;
-#endif
- return Resample_<BSincTag,CTag>;
- }
-
- return Resample_<PointTag,CTag>;
-}
-
-
void aluInitMixer()
{
if(auto resopt = ConfigValueStr(nullptr, nullptr, "resampler"))