aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/converter.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-20 03:35:41 -0800
committerChris Robinson <[email protected]>2018-11-20 03:35:41 -0800
commit66fdd027d027058792d56da741a7660d8646c9df (patch)
tree36010eb74ebe2fc6680718ee2a8a97cd5c110643 /Alc/converter.cpp
parentc7472f8642454830caf69bc163b0cfac61603d15 (diff)
Use more C++ templates instead of DECL_TEMPLATE tricks
Diffstat (limited to 'Alc/converter.cpp')
-rw-r--r--Alc/converter.cpp347
1 files changed, 145 insertions, 202 deletions
diff --git a/Alc/converter.cpp b/Alc/converter.cpp
index 5858c370..d64bc328 100644
--- a/Alc/converter.cpp
+++ b/Alc/converter.cpp
@@ -7,6 +7,133 @@
#include "mixer/defs.h"
+namespace {
+
+/* Base template left undefined. Should be marked =delete, but Clang 3.8.1
+ * chokes on that given the inline specializations.
+ */
+template<DevFmtType T>
+inline ALfloat LoadSample(typename DevFmtTypeTraits<T>::Type val);
+
+template<> inline ALfloat LoadSample<DevFmtByte>(DevFmtTypeTraits<DevFmtByte>::Type val)
+{ return val * (1.0f/128.0f); }
+template<> inline ALfloat LoadSample<DevFmtShort>(DevFmtTypeTraits<DevFmtShort>::Type val)
+{ return val * (1.0f/32768.0f); }
+template<> inline ALfloat LoadSample<DevFmtInt>(DevFmtTypeTraits<DevFmtInt>::Type val)
+{ return (val>>7) * (1.0f/16777216.0f); }
+template<> inline ALfloat LoadSample<DevFmtFloat>(DevFmtTypeTraits<DevFmtFloat>::Type val)
+{ return val; }
+
+template<> inline ALfloat LoadSample<DevFmtUByte>(DevFmtTypeTraits<DevFmtUByte>::Type val)
+{ return LoadSample<DevFmtByte>(val - 128); }
+template<> inline ALfloat LoadSample<DevFmtUShort>(DevFmtTypeTraits<DevFmtUShort>::Type val)
+{ return LoadSample<DevFmtByte>(val - 32768); }
+template<> inline ALfloat LoadSample<DevFmtUInt>(DevFmtTypeTraits<DevFmtUInt>::Type val)
+{ return LoadSample<DevFmtByte>(val - 2147483648u); }
+
+
+template<DevFmtType T>
+inline void LoadSampleArray(ALfloat *RESTRICT dst, const void *src, ALint srcstep, ALsizei samples)
+{
+ using SampleType = typename DevFmtTypeTraits<T>::Type;
+
+ const SampleType *ssrc = static_cast<const SampleType*>(src);
+ for(ALsizei i{0};i < samples;i++)
+ dst[i] = LoadSample<T>(ssrc[i*srcstep]);
+}
+
+void LoadSamples(ALfloat *dst, const ALvoid *src, ALint srcstep, enum DevFmtType srctype,
+ ALsizei samples)
+{
+#define HANDLE_FMT(T) \
+ case T: LoadSampleArray<T>(dst, src, srcstep, samples); break
+ switch(srctype)
+ {
+ HANDLE_FMT(DevFmtByte);
+ HANDLE_FMT(DevFmtUByte);
+ HANDLE_FMT(DevFmtShort);
+ HANDLE_FMT(DevFmtUShort);
+ HANDLE_FMT(DevFmtInt);
+ HANDLE_FMT(DevFmtUInt);
+ HANDLE_FMT(DevFmtFloat);
+ }
+#undef HANDLE_FMT
+}
+
+
+template<DevFmtType T>
+inline typename DevFmtTypeTraits<T>::Type StoreSample(ALfloat);
+
+template<> inline ALfloat StoreSample<DevFmtFloat>(ALfloat val)
+{ return val; }
+template<> inline ALint StoreSample<DevFmtInt>(ALfloat val)
+{ return fastf2i(clampf(val*16777216.0f, -16777216.0f, 16777215.0f))<<7; }
+template<> inline ALshort StoreSample<DevFmtShort>(ALfloat val)
+{ return fastf2i(clampf(val*32768.0f, -32768.0f, 32767.0f)); }
+template<> inline ALbyte StoreSample<DevFmtByte>(ALfloat val)
+{ return fastf2i(clampf(val*128.0f, -128.0f, 127.0f)); }
+
+/* Define unsigned output variations. */
+template<> inline ALuint StoreSample<DevFmtUInt>(ALfloat val)
+{ return StoreSample<DevFmtInt>(val) + 2147483648u; }
+template<> inline ALushort StoreSample<DevFmtUShort>(ALfloat val)
+{ return StoreSample<DevFmtShort>(val) + 32768; }
+template<> inline ALubyte StoreSample<DevFmtUByte>(ALfloat val)
+{ return StoreSample<DevFmtByte>(val) + 128; }
+
+template<DevFmtType T>
+inline void StoreSampleArray(void *dst, const ALfloat *RESTRICT src, ALint dststep,
+ ALsizei samples)
+{
+ using SampleType = typename DevFmtTypeTraits<T>::Type;
+
+ SampleType *sdst = static_cast<SampleType*>(dst);
+ for(ALsizei i{0};i < samples;i++)
+ sdst[i*dststep] = StoreSample<T>(src[i]);
+}
+
+
+void StoreSamples(ALvoid *dst, const ALfloat *src, ALint dststep, enum DevFmtType dsttype, ALsizei samples)
+{
+#define HANDLE_FMT(T) \
+ case T: StoreSampleArray<T>(dst, src, dststep, samples); break
+ switch(dsttype)
+ {
+ HANDLE_FMT(DevFmtByte);
+ HANDLE_FMT(DevFmtUByte);
+ HANDLE_FMT(DevFmtShort);
+ HANDLE_FMT(DevFmtUShort);
+ HANDLE_FMT(DevFmtInt);
+ HANDLE_FMT(DevFmtUInt);
+ HANDLE_FMT(DevFmtFloat);
+ }
+#undef HANDLE_FMT
+}
+
+
+template<DevFmtType T>
+void Mono2Stereo(ALfloat *RESTRICT dst, const void *src, ALsizei frames)
+{
+ using SampleType = typename DevFmtTypeTraits<T>::Type;
+
+ const SampleType *ssrc = static_cast<const SampleType*>(src);
+ for(ALsizei i{0};i < frames;i++)
+ dst[i*2 + 1] = dst[i*2 + 0] = LoadSample<T>(ssrc[i]) * 0.707106781187f;
+}
+
+template<DevFmtType T>
+void Stereo2Mono(ALfloat *RESTRICT dst, const void *src, ALsizei frames)
+{
+ using SampleType = typename DevFmtTypeTraits<T>::Type;
+
+ const SampleType *ssrc = static_cast<const SampleType*>(src);
+ for(ALsizei i{0};i < frames;i++)
+ dst[i] = (LoadSample<T>(ssrc[i*2 + 0])+LoadSample<T>(ssrc[i*2 + 1])) *
+ 0.707106781187f;
+}
+
+} // namespace
+
SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType dstType, ALsizei numchans, ALsizei srcRate, ALsizei dstRate)
{
SampleConverter *converter;
@@ -54,138 +181,6 @@ void DestroySampleConverter(SampleConverter **converter)
}
-static inline ALfloat Sample_ALbyte(ALbyte val)
-{ return val * (1.0f/128.0f); }
-static inline ALfloat Sample_ALubyte(ALubyte val)
-{ return Sample_ALbyte((ALint)val - 128); }
-
-static inline ALfloat Sample_ALshort(ALshort val)
-{ return val * (1.0f/32768.0f); }
-static inline ALfloat Sample_ALushort(ALushort val)
-{ return Sample_ALshort((ALint)val - 32768); }
-
-static inline ALfloat Sample_ALint(ALint val)
-{ return (val>>7) * (1.0f/16777216.0f); }
-static inline ALfloat Sample_ALuint(ALuint val)
-{ return Sample_ALint(val - INT_MAX - 1); }
-
-static inline ALfloat Sample_ALfloat(ALfloat val)
-{ return val; }
-
-#define DECL_TEMPLATE(T) \
-static inline void Load_##T(ALfloat *RESTRICT dst, const T *RESTRICT src, \
- ALint srcstep, ALsizei samples) \
-{ \
- ALsizei i; \
- for(i = 0;i < samples;i++) \
- dst[i] = Sample_##T(src[i*srcstep]); \
-}
-
-DECL_TEMPLATE(ALbyte)
-DECL_TEMPLATE(ALubyte)
-DECL_TEMPLATE(ALshort)
-DECL_TEMPLATE(ALushort)
-DECL_TEMPLATE(ALint)
-DECL_TEMPLATE(ALuint)
-DECL_TEMPLATE(ALfloat)
-
-#undef DECL_TEMPLATE
-
-static void LoadSamples(ALfloat *dst, const ALvoid *src, ALint srcstep, enum DevFmtType srctype, ALsizei samples)
-{
- switch(srctype)
- {
- case DevFmtByte:
- Load_ALbyte(dst, static_cast<const ALbyte*>(src), srcstep, samples);
- break;
- case DevFmtUByte:
- Load_ALubyte(dst, static_cast<const ALubyte*>(src), srcstep, samples);
- break;
- case DevFmtShort:
- Load_ALshort(dst, static_cast<const ALshort*>(src), srcstep, samples);
- break;
- case DevFmtUShort:
- Load_ALushort(dst, static_cast<const ALushort*>(src), srcstep, samples);
- break;
- case DevFmtInt:
- Load_ALint(dst, static_cast<const ALint*>(src), srcstep, samples);
- break;
- case DevFmtUInt:
- Load_ALuint(dst, static_cast<const ALuint*>(src), srcstep, samples);
- break;
- case DevFmtFloat:
- Load_ALfloat(dst, static_cast<const ALfloat*>(src), srcstep, samples);
- break;
- }
-}
-
-
-static inline ALbyte ALbyte_Sample(ALfloat val)
-{ return fastf2i(clampf(val*128.0f, -128.0f, 127.0f)); }
-static inline ALubyte ALubyte_Sample(ALfloat val)
-{ return ALbyte_Sample(val)+128; }
-
-static inline ALshort ALshort_Sample(ALfloat val)
-{ return fastf2i(clampf(val*32768.0f, -32768.0f, 32767.0f)); }
-static inline ALushort ALushort_Sample(ALfloat val)
-{ return ALshort_Sample(val)+32768; }
-
-static inline ALint ALint_Sample(ALfloat val)
-{ return fastf2i(clampf(val*16777216.0f, -16777216.0f, 16777215.0f)) << 7; }
-static inline ALuint ALuint_Sample(ALfloat val)
-{ return ALint_Sample(val)+INT_MAX+1; }
-
-static inline ALfloat ALfloat_Sample(ALfloat val)
-{ return val; }
-
-#define DECL_TEMPLATE(T) \
-static inline void Store_##T(T *RESTRICT dst, const ALfloat *RESTRICT src, \
- ALint dststep, ALsizei samples) \
-{ \
- ALsizei i; \
- for(i = 0;i < samples;i++) \
- dst[i*dststep] = T##_Sample(src[i]); \
-}
-
-DECL_TEMPLATE(ALbyte)
-DECL_TEMPLATE(ALubyte)
-DECL_TEMPLATE(ALshort)
-DECL_TEMPLATE(ALushort)
-DECL_TEMPLATE(ALint)
-DECL_TEMPLATE(ALuint)
-DECL_TEMPLATE(ALfloat)
-
-#undef DECL_TEMPLATE
-
-static void StoreSamples(ALvoid *dst, const ALfloat *src, ALint dststep, enum DevFmtType dsttype, ALsizei samples)
-{
- switch(dsttype)
- {
- case DevFmtByte:
- Store_ALbyte(static_cast<ALbyte*>(dst), src, dststep, samples);
- break;
- case DevFmtUByte:
- Store_ALubyte(static_cast<ALubyte*>(dst), src, dststep, samples);
- break;
- case DevFmtShort:
- Store_ALshort(static_cast<ALshort*>(dst), src, dststep, samples);
- break;
- case DevFmtUShort:
- Store_ALushort(static_cast<ALushort*>(dst), src, dststep, samples);
- break;
- case DevFmtInt:
- Store_ALint(static_cast<ALint*>(dst), src, dststep, samples);
- break;
- case DevFmtUInt:
- Store_ALuint(static_cast<ALuint*>(dst), src, dststep, samples);
- break;
- case DevFmtFloat:
- Store_ALfloat(static_cast<ALfloat*>(dst), src, dststep, samples);
- break;
- }
-}
-
-
ALsizei SampleConverterAvailableOut(SampleConverter *converter, ALsizei srcframes)
{
ALint prepcount = converter->mSrcPrepCount;
@@ -225,7 +220,6 @@ ALsizei SampleConverterAvailableOut(SampleConverter *converter, ALsizei srcframe
return (ALsizei)clampu64((DataSize64 + increment-1)/increment, 1, BUFFERSIZE);
}
-
ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALsizei *srcframes, ALvoid *dst, ALsizei dstframes)
{
const ALsizei SrcFrameSize = converter->mNumChannels * converter->mSrcTypeSize;
@@ -376,33 +370,6 @@ void DestroyChannelConverter(ChannelConverter **converter)
}
}
-
-#define DECL_TEMPLATE(T) \
-static void Mono2Stereo##T(ALfloat *RESTRICT dst, const T *src, ALsizei frames)\
-{ \
- ALsizei i; \
- for(i = 0;i < frames;i++) \
- dst[i*2 + 1] = dst[i*2 + 0] = Sample_##T(src[i]) * 0.707106781187f; \
-} \
- \
-static void Stereo2Mono##T(ALfloat *RESTRICT dst, const T *src, ALsizei frames)\
-{ \
- ALsizei i; \
- for(i = 0;i < frames;i++) \
- dst[i] = (Sample_##T(src[i*2 + 0])+Sample_##T(src[i*2 + 1])) * \
- 0.707106781187f; \
-}
-
-DECL_TEMPLATE(ALbyte)
-DECL_TEMPLATE(ALubyte)
-DECL_TEMPLATE(ALshort)
-DECL_TEMPLATE(ALushort)
-DECL_TEMPLATE(ALint)
-DECL_TEMPLATE(ALuint)
-DECL_TEMPLATE(ALfloat)
-
-#undef DECL_TEMPLATE
-
void ChannelConverterInput(ChannelConverter *converter, const ALvoid *src, ALfloat *dst, ALsizei frames)
{
if(converter->mSrcChans == converter->mDstChans)
@@ -416,54 +383,30 @@ void ChannelConverterInput(ChannelConverter *converter, const ALvoid *src, ALflo
{
switch(converter->mSrcType)
{
- case DevFmtByte:
- Stereo2MonoALbyte(dst, static_cast<const ALbyte*>(src), frames);
- break;
- case DevFmtUByte:
- Stereo2MonoALubyte(dst, static_cast<const ALubyte*>(src), frames);
- break;
- case DevFmtShort:
- Stereo2MonoALshort(dst, static_cast<const ALshort*>(src), frames);
- break;
- case DevFmtUShort:
- Stereo2MonoALushort(dst, static_cast<const ALushort*>(src), frames);
- break;
- case DevFmtInt:
- Stereo2MonoALint(dst, static_cast<const ALint*>(src), frames);
- break;
- case DevFmtUInt:
- Stereo2MonoALuint(dst, static_cast<const ALuint*>(src), frames);
- break;
- case DevFmtFloat:
- Stereo2MonoALfloat(dst, static_cast<const ALfloat*>(src), frames);
- break;
+#define HANDLE_FMT(T) case T: Stereo2Mono<T>(dst, src, frames); break
+ HANDLE_FMT(DevFmtByte);
+ HANDLE_FMT(DevFmtUByte);
+ HANDLE_FMT(DevFmtShort);
+ HANDLE_FMT(DevFmtUShort);
+ HANDLE_FMT(DevFmtInt);
+ HANDLE_FMT(DevFmtUInt);
+ HANDLE_FMT(DevFmtFloat);
+#undef HANDLE_FMT
}
}
else /*if(converter->mSrcChans == DevFmtMono && converter->mDstChans == DevFmtStereo)*/
{
switch(converter->mSrcType)
{
- case DevFmtByte:
- Mono2StereoALbyte(dst, static_cast<const ALbyte*>(src), frames);
- break;
- case DevFmtUByte:
- Mono2StereoALubyte(dst, static_cast<const ALubyte*>(src), frames);
- break;
- case DevFmtShort:
- Mono2StereoALshort(dst, static_cast<const ALshort*>(src), frames);
- break;
- case DevFmtUShort:
- Mono2StereoALushort(dst, static_cast<const ALushort*>(src), frames);
- break;
- case DevFmtInt:
- Mono2StereoALint(dst, static_cast<const ALint*>(src), frames);
- break;
- case DevFmtUInt:
- Mono2StereoALuint(dst, static_cast<const ALuint*>(src), frames);
- break;
- case DevFmtFloat:
- Mono2StereoALfloat(dst, static_cast<const ALfloat*>(src), frames);
- break;
+#define HANDLE_FMT(T) case T: Mono2Stereo<T>(dst, src, frames); break
+ HANDLE_FMT(DevFmtByte);
+ HANDLE_FMT(DevFmtUByte);
+ HANDLE_FMT(DevFmtShort);
+ HANDLE_FMT(DevFmtUShort);
+ HANDLE_FMT(DevFmtInt);
+ HANDLE_FMT(DevFmtUInt);
+ HANDLE_FMT(DevFmtFloat);
+#undef HANDLE_FMT
}
}
}