Don't apply distance attenuation when the slot's AuxSendAuto is off
[openal-soft.git] / al / eax / call.cpp
blob5c69d2e5ec978c97e3e611fdbb3e804e0cc3851f
1 #include "config.h"
2 #include "call.h"
3 #include "exception.h"
5 namespace {
7 constexpr auto deferred_flag = 0x80000000U;
9 class EaxCallException : public EaxException {
10 public:
11 explicit EaxCallException(const char* message)
12 : EaxException{"EAX_CALL", message}
14 }; // EaxCallException
16 } // namespace
18 EaxCall::EaxCall(EaxCallType type, const GUID &property_set_guid, ALuint property_id,
19 ALuint property_source_id, ALvoid *property_buffer, ALuint property_size)
20 : mCallType{type}, mIsDeferred{(property_id & deferred_flag) != 0}
21 , mPropertyId{property_id & ~deferred_flag}, mPropertySourceId{property_source_id}
22 , mPropertyBuffer{property_buffer}, mPropertyBufferSize{property_size}
24 switch(mCallType)
26 case EaxCallType::get:
27 case EaxCallType::set:
28 break;
30 default:
31 fail("Invalid type.");
34 if (false)
37 else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
39 mVersion = 4;
40 mPropertySetId = EaxCallPropertySetId::context;
42 else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
44 mVersion = 5;
45 mPropertySetId = EaxCallPropertySetId::context;
47 else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
49 mVersion = 2;
50 mFxSlotIndex = 0u;
51 mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
53 else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
55 mVersion = 3;
56 mFxSlotIndex = 0u;
57 mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
59 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
61 mVersion = 4;
62 mFxSlotIndex = 0u;
63 mPropertySetId = EaxCallPropertySetId::fx_slot;
65 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
67 mVersion = 5;
68 mFxSlotIndex = 0u;
69 mPropertySetId = EaxCallPropertySetId::fx_slot;
71 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
73 mVersion = 4;
74 mFxSlotIndex = 1u;
75 mPropertySetId = EaxCallPropertySetId::fx_slot;
77 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
79 mVersion = 5;
80 mFxSlotIndex = 1u;
81 mPropertySetId = EaxCallPropertySetId::fx_slot;
83 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
85 mVersion = 4;
86 mFxSlotIndex = 2u;
87 mPropertySetId = EaxCallPropertySetId::fx_slot;
89 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
91 mVersion = 5;
92 mFxSlotIndex = 2u;
93 mPropertySetId = EaxCallPropertySetId::fx_slot;
95 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
97 mVersion = 4;
98 mFxSlotIndex = 3u;
99 mPropertySetId = EaxCallPropertySetId::fx_slot;
101 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
103 mVersion = 5;
104 mFxSlotIndex = 3u;
105 mPropertySetId = EaxCallPropertySetId::fx_slot;
107 else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
109 mVersion = 2;
110 mPropertySetId = EaxCallPropertySetId::source;
112 else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
114 mVersion = 3;
115 mPropertySetId = EaxCallPropertySetId::source;
117 else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
119 mVersion = 4;
120 mPropertySetId = EaxCallPropertySetId::source;
122 else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
124 mVersion = 5;
125 mPropertySetId = EaxCallPropertySetId::source;
127 else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
129 mVersion = 1;
130 mFxSlotIndex = 0u;
131 mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
133 else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
135 mVersion = 1;
136 mPropertySetId = EaxCallPropertySetId::source;
138 else
140 fail("Unsupported property set id.");
143 if(mPropertySetId == EaxCallPropertySetId::context)
145 switch(mPropertyId)
147 case EAXCONTEXT_LASTERROR:
148 case EAXCONTEXT_SPEAKERCONFIG:
149 case EAXCONTEXT_EAXSESSION:
150 // EAX allow to set "defer" flag on immediate-only properties.
151 // If we don't clear our flag then "applyAllUpdates" in EAX context won't be called.
152 mIsDeferred = false;
153 break;
156 else if(mPropertySetId == EaxCallPropertySetId::fx_slot)
158 switch(mPropertyId)
160 case EAXFXSLOT_NONE:
161 case EAXFXSLOT_ALLPARAMETERS:
162 case EAXFXSLOT_LOADEFFECT:
163 case EAXFXSLOT_VOLUME:
164 case EAXFXSLOT_LOCK:
165 case EAXFXSLOT_FLAGS:
166 case EAXFXSLOT_OCCLUSION:
167 case EAXFXSLOT_OCCLUSIONLFRATIO:
168 mIsDeferred = false;
169 break;
173 if(!mIsDeferred)
175 if(mPropertySetId != EaxCallPropertySetId::fx_slot && mPropertyId != 0)
177 if(mPropertyBuffer == nullptr)
178 fail("Null property buffer.");
180 if(mPropertyBufferSize == 0)
181 fail("Empty property.");
185 if(mPropertySetId == EaxCallPropertySetId::source && mPropertySourceId == 0)
186 fail("Null AL source id.");
188 if(mPropertySetId == EaxCallPropertySetId::fx_slot)
190 if(mPropertyId < EAXFXSLOT_NONE)
191 mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
195 [[noreturn]] void EaxCall::fail(const char* message)
197 throw EaxCallException{message};
200 [[noreturn]] void EaxCall::fail_too_small()
202 fail("Property buffer too small.");
205 EaxCall create_eax_call(
206 EaxCallType type,
207 const GUID* property_set_id,
208 ALuint property_id,
209 ALuint property_source_id,
210 ALvoid* property_buffer,
211 ALuint property_size)
213 if(!property_set_id)
214 throw EaxCallException{"Null property set ID."};
216 return EaxCall{
217 type,
218 *property_set_id,
219 property_id,
220 property_source_id,
221 property_buffer,
222 property_size