aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-12-24 01:07:06 -0800
committerChris Robinson <[email protected]>2022-12-24 01:07:06 -0800
commitf177f62e6737fff413361fae89db728c7e3a0cf9 (patch)
tree4eb1f7c9424b3e0a4be0b97bd5b9484793736393
parent17f725d41837acbf6cc617b3032e4a064b685833 (diff)
Avoid some macros for checking property sizes and values
-rw-r--r--al/source.cpp397
1 files changed, 228 insertions, 169 deletions
diff --git a/al/source.cpp b/al/source.cpp
index 477fdb5d..c18df656 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -1008,7 +1008,7 @@ enum SourceProp : ALenum {
constexpr size_t MaxValues{6u};
-ALuint FloatValsByProp(ALenum prop)
+constexpr ALuint FloatValsByProp(ALenum prop)
{
switch(static_cast<SourceProp>(prop))
{
@@ -1075,7 +1075,7 @@ ALuint FloatValsByProp(ALenum prop)
}
return 0;
}
-ALuint DoubleValsByProp(ALenum prop)
+constexpr ALuint DoubleValsByProp(ALenum prop)
{
switch(static_cast<SourceProp>(prop))
{
@@ -1146,18 +1146,17 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<const int> values);
void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<const int64_t> values);
-#define CHECKSIZE(v, s) do { \
- if((v).size() == (s) || (v).size() == MaxValues) [[likely]] break; \
- Context->setError(AL_INVALID_ENUM, \
- "Property 0x%04x expects %d value(s), got %zu", prop, (s), \
- (v).size()); \
- return; \
-} while(0)
-#define CHECKVAL(x) do { \
- if(x) [[likely]] break; \
- Context->setError(AL_INVALID_VALUE, "Value out of range"); \
- return; \
-} while(0)
+struct check_exception : std::exception {
+};
+struct check_size_exception final : check_exception {
+ const char *what() const noexcept override
+ { return "check_size_exception"; }
+};
+struct check_value_exception final : check_exception {
+ const char *what() const noexcept override
+ { return "check_value_exception"; }
+};
+
void UpdateSourceProps(ALsource *source, ALCcontext *context)
{
@@ -1194,9 +1193,43 @@ inline void CommitAndUpdateSourceProps(ALsource *source, ALCcontext *context)
#endif
+/**
+ * Returns a pair of lambdas to check the following setters and getters.
+ *
+ * The first lambda checks the size of the span is valid for its given size,
+ * setting the proper context error and throwing a check_size_exception if it
+ * fails.
+ *
+ * The second lambda tests the validity of the value check, setting the proper
+ * context error and throwing a check_value_exception if it failed.
+ */
+template<typename T, size_t N>
+auto GetCheckers(ALCcontext *Context, const SourceProp prop, const al::span<T,N> values)
+{
+ return std::make_pair(
+ [=](size_t expect) -> void
+ {
+ if(values.size() == expect || values.size() == MaxValues) [[likely]] return;
+ Context->setError(AL_INVALID_ENUM, "Property 0x%04x expects %zu value(s), got %zu",
+ prop, expect, values.size());
+ throw check_size_exception{};
+ },
+ [Context](bool passed) -> void
+ {
+ if(passed) [[likely]] return;
+ Context->setError(AL_INVALID_VALUE, "Value out of range");
+ throw check_value_exception{};
+ }
+ );
+}
+
void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
const al::span<const float> values)
-{
+try {
+ /* Structured bindings would be nice (C++17). */
+ auto Checkers = GetCheckers(Context, prop, values);
+ auto &CheckSize = Checkers.first;
+ auto &CheckValue = Checkers.second;
int ival;
switch(prop)
@@ -1209,99 +1242,99 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
"Setting read-only source property 0x%04x", prop);
case AL_PITCH:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->Pitch = values[0];
return UpdateSourceProps(Source, Context);
case AL_CONE_INNER_ANGLE:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 360.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 360.0f);
Source->InnerAngle = values[0];
return CommitAndUpdateSourceProps(Source, Context);
case AL_CONE_OUTER_ANGLE:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 360.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 360.0f);
Source->OuterAngle = values[0];
return CommitAndUpdateSourceProps(Source, Context);
case AL_GAIN:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->Gain = values[0];
return UpdateSourceProps(Source, Context);
case AL_MAX_DISTANCE:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->MaxDistance = values[0];
return CommitAndUpdateSourceProps(Source, Context);
case AL_ROLLOFF_FACTOR:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->RolloffFactor = values[0];
return CommitAndUpdateSourceProps(Source, Context);
case AL_REFERENCE_DISTANCE:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->RefDistance = values[0];
return CommitAndUpdateSourceProps(Source, Context);
case AL_MIN_GAIN:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->MinGain = values[0];
return UpdateSourceProps(Source, Context);
case AL_MAX_GAIN:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f);
Source->MaxGain = values[0];
return UpdateSourceProps(Source, Context);
case AL_CONE_OUTER_GAIN:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 1.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 1.0f);
Source->OuterGain = values[0];
return UpdateSourceProps(Source, Context);
case AL_CONE_OUTER_GAINHF:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 1.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 1.0f);
Source->OuterGainHF = values[0];
return UpdateSourceProps(Source, Context);
case AL_AIR_ABSORPTION_FACTOR:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 10.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 10.0f);
Source->AirAbsorptionFactor = values[0];
return UpdateSourceProps(Source, Context);
case AL_ROOM_ROLLOFF_FACTOR:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 10.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 10.0f);
Source->RoomRolloffFactor = values[0];
return UpdateSourceProps(Source, Context);
case AL_DOPPLER_FACTOR:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 1.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 1.0f);
Source->DopplerFactor = values[0];
return UpdateSourceProps(Source, Context);
@@ -1309,8 +1342,8 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_SEC_OFFSET:
case AL_SAMPLE_OFFSET:
case AL_BYTE_OFFSET:
- CHECKSIZE(values, 1);
- CHECKVAL(std::isfinite(values[0]));
+ CheckSize(1);
+ CheckValue(std::isfinite(values[0]));
if(Voice *voice{GetSourceVoice(Source, Context)})
{
@@ -1325,22 +1358,22 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_SOURCE_RADIUS:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && std::isfinite(values[0]));
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && std::isfinite(values[0]));
Source->Radius = values[0];
return UpdateSourceProps(Source, Context);
case AL_SUPER_STEREO_WIDTH_SOFT:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0.0f && values[0] <= 1.0f);
+ CheckSize(1);
+ CheckValue(values[0] >= 0.0f && values[0] <= 1.0f);
Source->EnhWidth = values[0];
return UpdateSourceProps(Source, Context);
case AL_STEREO_ANGLES:
- CHECKSIZE(values, 2);
- CHECKVAL(std::isfinite(values[0]) && std::isfinite(values[1]));
+ CheckSize(2);
+ CheckValue(std::isfinite(values[0]) && std::isfinite(values[1]));
Source->StereoPan[0] = values[0];
Source->StereoPan[1] = values[1];
@@ -1348,8 +1381,8 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_POSITION:
- CHECKSIZE(values, 3);
- CHECKVAL(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]));
+ CheckSize(3);
+ CheckValue(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]));
Source->Position[0] = values[0];
Source->Position[1] = values[1];
@@ -1357,8 +1390,8 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return CommitAndUpdateSourceProps(Source, Context);
case AL_VELOCITY:
- CHECKSIZE(values, 3);
- CHECKVAL(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]));
+ CheckSize(3);
+ CheckValue(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]));
Source->Velocity[0] = values[0];
Source->Velocity[1] = values[1];
@@ -1366,8 +1399,8 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return CommitAndUpdateSourceProps(Source, Context);
case AL_DIRECTION:
- CHECKSIZE(values, 3);
- CHECKVAL(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]));
+ CheckSize(3);
+ CheckValue(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2]));
Source->Direction[0] = values[0];
Source->Direction[1] = values[1];
@@ -1375,8 +1408,8 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return CommitAndUpdateSourceProps(Source, Context);
case AL_ORIENTATION:
- CHECKSIZE(values, 6);
- CHECKVAL(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2])
+ CheckSize(6);
+ CheckValue(std::isfinite(values[0]) && std::isfinite(values[1]) && std::isfinite(values[2])
&& std::isfinite(values[3]) && std::isfinite(values[4]) && std::isfinite(values[5]));
Source->OrientAt[0] = values[0];
@@ -1402,13 +1435,13 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_BYTE_LENGTH_SOFT:
case AL_SAMPLE_LENGTH_SOFT:
case AL_STEREO_MODE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
ival = static_cast<int>(values[0]);
return SetSourceiv(Source, Context, prop, {&ival, 1u});
case AL_BUFFERS_QUEUED:
case AL_BUFFERS_PROCESSED:
- CHECKSIZE(values, 1);
+ CheckSize(1);
ival = static_cast<int>(static_cast<ALuint>(values[0]));
return SetSourceiv(Source, Context, prop, {&ival, 1u});
@@ -1422,12 +1455,16 @@ void SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop,
ERR("Unexpected property: 0x%04x\n", prop);
Context->setError(AL_INVALID_ENUM, "Invalid source float property 0x%04x", prop);
- return;
+}
+catch(check_exception&) {
}
void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
const al::span<const int> values)
-{
+try {
+ auto Checkers = GetCheckers(Context, prop, values);
+ auto &CheckSize = Checkers.first;
+ auto &CheckValue = Checkers.second;
ALCdevice *device{Context->mALDevice.get()};
ALeffectslot *slot{nullptr};
al::deque<ALbufferQueueItem> oldlist;
@@ -1447,15 +1484,15 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
"Setting read-only source property 0x%04x", prop);
case AL_SOURCE_RELATIVE:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
+ CheckSize(1);
+ CheckValue(values[0] == AL_FALSE || values[0] == AL_TRUE);
Source->HeadRelative = values[0] != AL_FALSE;
return CommitAndUpdateSourceProps(Source, Context);
case AL_LOOPING:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
+ CheckSize(1);
+ CheckValue(values[0] == AL_FALSE || values[0] == AL_TRUE);
Source->Looping = values[0] != AL_FALSE;
if(Voice *voice{GetSourceVoice(Source, Context)})
@@ -1473,7 +1510,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_BUFFER:
- CHECKSIZE(values, 1);
+ CheckSize(1);
{
const ALenum state{GetSourceState(Source, GetSourceVoice(Source, Context))};
if(state == AL_PLAYING || state == AL_PAUSED)
@@ -1529,7 +1566,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_SEC_OFFSET:
case AL_SAMPLE_OFFSET:
case AL_BYTE_OFFSET:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if(Voice *voice{GetSourceVoice(Source, Context)})
{
@@ -1544,7 +1581,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_DIRECT_FILTER:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if(values[0])
{
std::lock_guard<std::mutex> _{device->FilterLock};
@@ -1569,28 +1606,28 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return UpdateSourceProps(Source, Context);
case AL_DIRECT_FILTER_GAINHF_AUTO:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
+ CheckSize(1);
+ CheckValue(values[0] == AL_FALSE || values[0] == AL_TRUE);
Source->DryGainHFAuto = values[0] != AL_FALSE;
return UpdateSourceProps(Source, Context);
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
+ CheckSize(1);
+ CheckValue(values[0] == AL_FALSE || values[0] == AL_TRUE);
Source->WetGainAuto = values[0] != AL_FALSE;
return UpdateSourceProps(Source, Context);
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
+ CheckSize(1);
+ CheckValue(values[0] == AL_FALSE || values[0] == AL_TRUE);
Source->WetGainHFAuto = values[0] != AL_FALSE;
return UpdateSourceProps(Source, Context);
case AL_DIRECT_CHANNELS_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if(auto mode = DirectModeFromEnum(values[0]))
{
Source->DirectChannels = *mode;
@@ -1601,7 +1638,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_DISTANCE_MODEL:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if(auto model = DistanceModelFromALenum(values[0]))
{
Source->mDistanceModel = *model;
@@ -1613,14 +1650,14 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_SOURCE_RESAMPLER_SOFT:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] >= 0 && values[0] <= static_cast<int>(Resampler::Max));
+ CheckSize(1);
+ CheckValue(values[0] >= 0 && values[0] <= static_cast<int>(Resampler::Max));
Source->mResampler = static_cast<Resampler>(values[0]);
return UpdateSourceProps(Source, Context);
case AL_SOURCE_SPATIALIZE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if(auto mode = SpatializeModeFromEnum(values[0]))
{
Source->mSpatialize = *mode;
@@ -1631,7 +1668,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_STEREO_MODE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
{
const ALenum state{GetSourceState(Source, GetSourceVoice(Source, Context))};
if(state == AL_PLAYING || state == AL_PAUSED)
@@ -1648,7 +1685,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
return;
case AL_AUXILIARY_SEND_FILTER:
- CHECKSIZE(values, 3);
+ CheckSize(3);
slotlock = std::unique_lock<std::mutex>{Context->mEffectSlotLock};
if(values[0] && (slot=LookupEffectSlot(Context, static_cast<ALuint>(values[0]))) == nullptr)
SETERR_RETURN(Context, AL_INVALID_VALUE,, "Invalid effect ID %u", values[0]);
@@ -1724,7 +1761,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_SOURCE_RADIUS:
case AL_SEC_LENGTH_SOFT:
case AL_SUPER_STEREO_WIDTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
fvals[0] = static_cast<float>(values[0]);
return SetSourcefv(Source, Context, prop, {fvals, 1u});
@@ -1732,7 +1769,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_POSITION:
case AL_VELOCITY:
case AL_DIRECTION:
- CHECKSIZE(values, 3);
+ CheckSize(3);
fvals[0] = static_cast<float>(values[0]);
fvals[1] = static_cast<float>(values[1]);
fvals[2] = static_cast<float>(values[2]);
@@ -1740,7 +1777,7 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
/* 6x float */
case AL_ORIENTATION:
- CHECKSIZE(values, 6);
+ CheckSize(6);
fvals[0] = static_cast<float>(values[0]);
fvals[1] = static_cast<float>(values[1]);
fvals[2] = static_cast<float>(values[2]);
@@ -1759,12 +1796,16 @@ void SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
ERR("Unexpected property: 0x%04x\n", prop);
Context->setError(AL_INVALID_ENUM, "Invalid source integer property 0x%04x", prop);
- return;
+}
+catch(check_exception&) {
}
void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
const al::span<const int64_t> values)
-{
+try {
+ auto Checkers = GetCheckers(Context, prop, values);
+ auto &CheckSize = Checkers.first;
+ auto &CheckValue = Checkers.second;
float fvals[MaxValues];
int ivals[MaxValues];
@@ -1796,8 +1837,8 @@ void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_SOURCE_RESAMPLER_SOFT:
case AL_SOURCE_SPATIALIZE_SOFT:
case AL_STEREO_MODE_SOFT:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] <= INT_MAX && values[0] >= INT_MIN);
+ CheckSize(1);
+ CheckValue(values[0] <= INT_MAX && values[0] >= INT_MIN);
ivals[0] = static_cast<int>(values[0]);
return SetSourceiv(Source, Context, prop, {ivals, 1u});
@@ -1805,17 +1846,17 @@ void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
/* 1x uint */
case AL_BUFFER:
case AL_DIRECT_FILTER:
- CHECKSIZE(values, 1);
- CHECKVAL(values[0] <= UINT_MAX && values[0] >= 0);
+ CheckSize(1);
+ CheckValue(values[0] <= UINT_MAX && values[0] >= 0);
ivals[0] = static_cast<int>(values[0]);
return SetSourceiv(Source, Context, prop, {ivals, 1u});
/* 3x uint */
case AL_AUXILIARY_SEND_FILTER:
- CHECKSIZE(values, 3);
- CHECKVAL(values[0] <= UINT_MAX && values[0] >= 0 && values[1] <= UINT_MAX && values[1] >= 0
- && values[2] <= UINT_MAX && values[2] >= 0);
+ CheckSize(3);
+ CheckValue(values[0] <= UINT_MAX && values[0] >= 0 && values[1] <= UINT_MAX
+ && values[1] >= 0 && values[2] <= UINT_MAX && values[2] >= 0);
ivals[0] = static_cast<int>(values[0]);
ivals[1] = static_cast<int>(values[1]);
@@ -1840,7 +1881,7 @@ void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_SOURCE_RADIUS:
case AL_SEC_LENGTH_SOFT:
case AL_SUPER_STEREO_WIDTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
fvals[0] = static_cast<float>(values[0]);
return SetSourcefv(Source, Context, prop, {fvals, 1u});
@@ -1848,7 +1889,7 @@ void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
case AL_POSITION:
case AL_VELOCITY:
case AL_DIRECTION:
- CHECKSIZE(values, 3);
+ CheckSize(3);
fvals[0] = static_cast<float>(values[0]);
fvals[1] = static_cast<float>(values[1]);
fvals[2] = static_cast<float>(values[2]);
@@ -1856,7 +1897,7 @@ void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
/* 6x float */
case AL_ORIENTATION:
- CHECKSIZE(values, 6);
+ CheckSize(6);
fvals[0] = static_cast<float>(values[0]);
fvals[1] = static_cast<float>(values[1]);
fvals[2] = static_cast<float>(values[2]);
@@ -1873,26 +1914,31 @@ void SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
ERR("Unexpected property: 0x%04x\n", prop);
Context->setError(AL_INVALID_ENUM, "Invalid source integer64 property 0x%04x", prop);
- return;
+}
+catch(check_exception&) {
}
-#undef CHECKVAL
-#undef CHECKSIZE
-#define CHECKSIZE(v, s) do { \
- if((v).size() == (s) || (v).size() == MaxValues) [[likely]] break; \
- Context->setError(AL_INVALID_ENUM, \
- "Property 0x%04x expects %d value(s), got %zu", prop, (s), \
- (v).size()); \
- return false; \
-} while(0)
+template<typename T, size_t N>
+auto GetSizeChecker(ALCcontext *Context, const SourceProp prop, const al::span<T,N> values)
+{
+ return [=](size_t expect) -> void
+ {
+ if(values.size() == expect || values.size() == MaxValues) [[likely]] return;
+ Context->setError(AL_INVALID_ENUM, "Property 0x%04x expects %zu value(s), got %zu",
+ prop, expect, values.size());
+ throw check_size_exception{};
+ };
+}
bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<double> values);
bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<int> values);
bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<int64_t> values);
-bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<double> values)
-{
+bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop,
+ const al::span<double> values)
+try {
+ auto CheckSize = GetSizeChecker(Context, prop, values);
ALCdevice *device{Context->mALDevice.get()};
ClockLatency clocktime;
nanoseconds srcclock;
@@ -1902,107 +1948,107 @@ bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
switch(prop)
{
case AL_GAIN:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->Gain;
return true;
case AL_PITCH:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->Pitch;
return true;
case AL_MAX_DISTANCE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->MaxDistance;
return true;
case AL_ROLLOFF_FACTOR:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->RolloffFactor;
return true;
case AL_REFERENCE_DISTANCE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->RefDistance;
return true;
case AL_CONE_INNER_ANGLE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->InnerAngle;
return true;
case AL_CONE_OUTER_ANGLE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->OuterAngle;
return true;
case AL_MIN_GAIN:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->MinGain;
return true;
case AL_MAX_GAIN:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->MaxGain;
return true;
case AL_CONE_OUTER_GAIN:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->OuterGain;
return true;
case AL_SEC_OFFSET:
case AL_SAMPLE_OFFSET:
case AL_BYTE_OFFSET:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = GetSourceOffset(Source, prop, Context);
return true;
case AL_CONE_OUTER_GAINHF:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->OuterGainHF;
return true;
case AL_AIR_ABSORPTION_FACTOR:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->AirAbsorptionFactor;
return true;
case AL_ROOM_ROLLOFF_FACTOR:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->RoomRolloffFactor;
return true;
case AL_DOPPLER_FACTOR:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->DopplerFactor;
return true;
case AL_SOURCE_RADIUS:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->Radius;
return true;
case AL_SUPER_STEREO_WIDTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->EnhWidth;
return true;
case AL_BYTE_LENGTH_SOFT:
case AL_SAMPLE_LENGTH_SOFT:
case AL_SEC_LENGTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = GetSourceLength(Source, prop);
return true;
case AL_STEREO_ANGLES:
- CHECKSIZE(values, 2);
+ CheckSize(2);
values[0] = Source->StereoPan[0];
values[1] = Source->StereoPan[1];
return true;
case AL_SEC_OFFSET_LATENCY_SOFT:
- CHECKSIZE(values, 2);
+ CheckSize(2);
/* Get the source offset with the clock time first. Then get the clock
* time with the device latency. Order is important.
*/
@@ -2025,34 +2071,34 @@ bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
return true;
case AL_SEC_OFFSET_CLOCK_SOFT:
- CHECKSIZE(values, 2);
+ CheckSize(2);
values[0] = GetSourceSecOffset(Source, Context, &srcclock);
values[1] = static_cast<double>(srcclock.count()) / 1000000000.0;
return true;
case AL_POSITION:
- CHECKSIZE(values, 3);
+ CheckSize(3);
values[0] = Source->Position[0];
values[1] = Source->Position[1];
values[2] = Source->Position[2];
return true;
case AL_VELOCITY:
- CHECKSIZE(values, 3);
+ CheckSize(3);
values[0] = Source->Velocity[0];
values[1] = Source->Velocity[1];
values[2] = Source->Velocity[2];
return true;
case AL_DIRECTION:
- CHECKSIZE(values, 3);
+ CheckSize(3);
values[0] = Source->Direction[0];
values[1] = Source->Direction[1];
values[2] = Source->Direction[2];
return true;
case AL_ORIENTATION:
- CHECKSIZE(values, 6);
+ CheckSize(6);
values[0] = Source->OrientAt[0];
values[1] = Source->OrientAt[1];
values[2] = Source->OrientAt[2];
@@ -2076,7 +2122,7 @@ bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
case AL_SOURCE_RESAMPLER_SOFT:
case AL_SOURCE_SPATIALIZE_SOFT:
case AL_STEREO_MODE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if((err=GetSourceiv(Source, Context, prop, {ivals, 1u})) != false)
values[0] = static_cast<double>(ivals[0]);
return err;
@@ -2093,26 +2139,31 @@ bool GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
Context->setError(AL_INVALID_ENUM, "Invalid source double property 0x%04x", prop);
return false;
}
+catch(check_exception&) {
+ return false;
+}
-bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<int> values)
-{
+bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop,
+ const al::span<int> values)
+try {
+ auto CheckSize = GetSizeChecker(Context, prop, values);
double dvals[MaxValues];
bool err;
switch(prop)
{
case AL_SOURCE_RELATIVE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->HeadRelative;
return true;
case AL_LOOPING:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->Looping;
return true;
case AL_BUFFER:
- CHECKSIZE(values, 1);
+ CheckSize(1);
{
ALbufferQueueItem *BufferList{(Source->SourceType == AL_STATIC)
? &Source->mQueue.front() : nullptr};
@@ -2122,17 +2173,17 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
return true;
case AL_SOURCE_STATE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = GetSourceState(Source, GetSourceVoice(Source, Context));
return true;
case AL_BUFFERS_QUEUED:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = static_cast<int>(Source->mQueue.size());
return true;
case AL_BUFFERS_PROCESSED:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if(Source->Looping || Source->SourceType != AL_STREAMING)
{
/* Buffers on a looping source are in a perpetual state of PENDING,
@@ -2160,55 +2211,55 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
return true;
case AL_SOURCE_TYPE:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->SourceType;
return true;
case AL_DIRECT_FILTER_GAINHF_AUTO:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->DryGainHFAuto;
return true;
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->WetGainAuto;
return true;
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = Source->WetGainHFAuto;
return true;
case AL_DIRECT_CHANNELS_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = EnumFromDirectMode(Source->DirectChannels);
return true;
case AL_DISTANCE_MODEL:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = ALenumFromDistanceModel(Source->mDistanceModel);
return true;
case AL_BYTE_LENGTH_SOFT:
case AL_SAMPLE_LENGTH_SOFT:
case AL_SEC_LENGTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = static_cast<int>(mind(GetSourceLength(Source, prop),
std::numeric_limits<int>::max()));
return true;
case AL_SOURCE_RESAMPLER_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = static_cast<int>(Source->mResampler);
return true;
case AL_SOURCE_SPATIALIZE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = EnumFromSpatializeMode(Source->mSpatialize);
return true;
case AL_STEREO_MODE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = EnumFromStereoMode(Source->mStereoMode);
return true;
@@ -2232,7 +2283,7 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
case AL_CONE_OUTER_GAINHF:
case AL_SOURCE_RADIUS:
case AL_SUPER_STEREO_WIDTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if((err=GetSourcedv(Source, Context, prop, {dvals, 1u})) != false)
values[0] = static_cast<int>(dvals[0]);
return err;
@@ -2241,7 +2292,7 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
case AL_POSITION:
case AL_VELOCITY:
case AL_DIRECTION:
- CHECKSIZE(values, 3);
+ CheckSize(3);
if((err=GetSourcedv(Source, Context, prop, {dvals, 3u})) != false)
{
values[0] = static_cast<int>(dvals[0]);
@@ -2252,7 +2303,7 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
/* 6x float/double */
case AL_ORIENTATION:
- CHECKSIZE(values, 6);
+ CheckSize(6);
if((err=GetSourcedv(Source, Context, prop, {dvals, 6u})) != false)
{
values[0] = static_cast<int>(dvals[0]);
@@ -2282,9 +2333,14 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
Context->setError(AL_INVALID_ENUM, "Invalid source integer property 0x%04x", prop);
return false;
}
+catch(check_exception&) {
+ return false;
+}
-bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<int64_t> values)
-{
+bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
+ const al::span<int64_t> values)
+try {
+ auto CheckSize = GetSizeChecker(Context, prop, values);
ALCdevice *device{Context->mALDevice.get()};
ClockLatency clocktime;
nanoseconds srcclock;
@@ -2297,12 +2353,12 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
case AL_BYTE_LENGTH_SOFT:
case AL_SAMPLE_LENGTH_SOFT:
case AL_SEC_LENGTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
values[0] = static_cast<int64_t>(GetSourceLength(Source, prop));
return true;
case AL_SAMPLE_OFFSET_LATENCY_SOFT:
- CHECKSIZE(values, 2);
+ CheckSize(2);
/* Get the source offset with the clock time first. Then get the clock
* time with the device latency. Order is important.
*/
@@ -2324,7 +2380,7 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
return true;
case AL_SAMPLE_OFFSET_CLOCK_SOFT:
- CHECKSIZE(values, 2);
+ CheckSize(2);
values[0] = GetSourceSampleOffset(Source, Context, &srcclock);
values[1] = srcclock.count();
return true;
@@ -2349,7 +2405,7 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
case AL_CONE_OUTER_GAINHF:
case AL_SOURCE_RADIUS:
case AL_SUPER_STEREO_WIDTH_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if((err=GetSourcedv(Source, Context, prop, {dvals, 1u})) != false)
values[0] = static_cast<int64_t>(dvals[0]);
return err;
@@ -2358,7 +2414,7 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
case AL_POSITION:
case AL_VELOCITY:
case AL_DIRECTION:
- CHECKSIZE(values, 3);
+ CheckSize(3);
if((err=GetSourcedv(Source, Context, prop, {dvals, 3u})) != false)
{
values[0] = static_cast<int64_t>(dvals[0]);
@@ -2369,7 +2425,7 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
/* 6x float/double */
case AL_ORIENTATION:
- CHECKSIZE(values, 6);
+ CheckSize(6);
if((err=GetSourcedv(Source, Context, prop, {dvals, 6u})) != false)
{
values[0] = static_cast<int64_t>(dvals[0]);
@@ -2396,7 +2452,7 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
case AL_SOURCE_RESAMPLER_SOFT:
case AL_SOURCE_SPATIALIZE_SOFT:
case AL_STEREO_MODE_SOFT:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if((err=GetSourceiv(Source, Context, prop, {ivals, 1u})) != false)
values[0] = ivals[0];
return err;
@@ -2404,14 +2460,14 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
/* 1x uint */
case AL_BUFFER:
case AL_DIRECT_FILTER:
- CHECKSIZE(values, 1);
+ CheckSize(1);
if((err=GetSourceiv(Source, Context, prop, {ivals, 1u})) != false)
values[0] = static_cast<ALuint>(ivals[0]);
return err;
/* 3x uint */
case AL_AUXILIARY_SEND_FILTER:
- CHECKSIZE(values, 3);
+ CheckSize(3);
if((err=GetSourceiv(Source, Context, prop, {ivals, 3u})) != false)
{
values[0] = static_cast<ALuint>(ivals[0]);
@@ -2431,6 +2487,9 @@ bool GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const
Context->setError(AL_INVALID_ENUM, "Invalid source integer64 property 0x%04x", prop);
return false;
}
+catch(check_exception&) {
+ return false;
+}
void StartSources(ALCcontext *context, const al::span<ALsource*> srchandles,
@@ -2591,7 +2650,7 @@ void StartSources(ALCcontext *context, const al::span<ALsource*> srchandles,
voice->mFlags.set(VoiceIsFading);
}
}
- InitVoice(voice, source, std::addressof(*BufferList), context, device);
+ InitVoice(voice, source, al::to_address(BufferList), context, device);
source->VoiceIdx = vidx;
source->state = AL_PLAYING;