Check for a minimum PipeWire version
[openal-soft.git] / al / eax_eax_call.cpp
blob914d2fbfaaa330d092c636b516f7b075b38beb58
1 #include "config.h"
3 #include "al/eax_eax_call.h"
5 #include "al/eax_exception.h"
8 namespace {
10 constexpr auto deferred_flag = 0x80000000U;
12 class EaxEaxCallException :
13 public EaxException
15 public:
16 explicit EaxEaxCallException(
17 const char* message)
19 EaxException{"EAX_EAX_CALL", message}
22 }; // EaxEaxCallException
24 } // namespace
27 EaxEaxCall::EaxEaxCall(
28 bool is_get,
29 const GUID& property_set_guid,
30 ALuint property_id,
31 ALuint property_source_id,
32 ALvoid* property_buffer,
33 ALuint property_size)
34 : is_get_{is_get}, version_{0}, property_set_id_{EaxEaxCallPropertySetId::none}
35 , property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
36 , property_buffer_{property_buffer}, property_size_{property_size}
38 if (false)
41 else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
43 version_ = 4;
44 property_set_id_ = EaxEaxCallPropertySetId::context;
46 else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
48 version_ = 5;
49 property_set_id_ = EaxEaxCallPropertySetId::context;
51 else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
53 version_ = 2;
54 fx_slot_index_ = 0u;
55 property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
56 property_id_ = convert_eax_v2_0_listener_property_id(property_id_);
58 else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
60 version_ = 3;
61 fx_slot_index_ = 0u;
62 property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
64 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
66 version_ = 4;
67 fx_slot_index_ = 0u;
68 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
70 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
72 version_ = 5;
73 fx_slot_index_ = 0u;
74 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
76 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
78 version_ = 4;
79 fx_slot_index_ = 1u;
80 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
82 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
84 version_ = 5;
85 fx_slot_index_ = 1u;
86 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
88 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
90 version_ = 4;
91 fx_slot_index_ = 2u;
92 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
94 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
96 version_ = 5;
97 fx_slot_index_ = 2u;
98 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
100 else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
102 version_ = 4;
103 fx_slot_index_ = 3u;
104 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
106 else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
108 version_ = 5;
109 fx_slot_index_ = 3u;
110 property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
112 else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
114 version_ = 2;
115 property_set_id_ = EaxEaxCallPropertySetId::source;
116 property_id_ = convert_eax_v2_0_buffer_property_id(property_id_);
118 else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
120 version_ = 3;
121 property_set_id_ = EaxEaxCallPropertySetId::source;
123 else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
125 version_ = 4;
126 property_set_id_ = EaxEaxCallPropertySetId::source;
128 else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
130 version_ = 5;
131 property_set_id_ = EaxEaxCallPropertySetId::source;
133 else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
135 version_ = 1;
136 fx_slot_index_ = 0u;
137 property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
139 else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
141 version_ = 1;
142 property_set_id_ = EaxEaxCallPropertySetId::source;
144 else
146 fail("Unsupported property set id.");
149 if (version_ < 1 || version_ > 5)
151 fail("EAX version out of range.");
154 if(!(property_id&deferred_flag))
156 if(property_set_id_ != EaxEaxCallPropertySetId::fx_slot && property_id_ != 0)
158 if (!property_buffer)
160 fail("Null property buffer.");
163 if (property_size == 0)
165 fail("Empty property.");
170 if(property_set_id_ == EaxEaxCallPropertySetId::source && property_source_id_ == 0)
172 fail("Null AL source id.");
175 if (property_set_id_ == EaxEaxCallPropertySetId::fx_slot)
177 if (property_id_ < EAXFXSLOT_NONE)
179 property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
184 [[noreturn]]
185 void EaxEaxCall::fail(
186 const char* message)
188 throw EaxEaxCallException{message};
191 ALuint EaxEaxCall::convert_eax_v2_0_listener_property_id(
192 ALuint property_id)
194 switch (property_id)
196 case DSPROPERTY_EAX20LISTENER_NONE:
197 return EAXREVERB_NONE;
199 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
200 return EAXREVERB_ALLPARAMETERS;
202 case DSPROPERTY_EAX20LISTENER_ROOM:
203 return EAXREVERB_ROOM;
205 case DSPROPERTY_EAX20LISTENER_ROOMHF:
206 return EAXREVERB_ROOMHF;
208 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
209 return EAXREVERB_ROOMROLLOFFFACTOR;
211 case DSPROPERTY_EAX20LISTENER_DECAYTIME:
212 return EAXREVERB_DECAYTIME;
214 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
215 return EAXREVERB_DECAYHFRATIO;
217 case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
218 return EAXREVERB_REFLECTIONS;
220 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
221 return EAXREVERB_REFLECTIONSDELAY;
223 case DSPROPERTY_EAX20LISTENER_REVERB:
224 return EAXREVERB_REVERB;
226 case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
227 return EAXREVERB_REVERBDELAY;
229 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
230 return EAXREVERB_ENVIRONMENT;
232 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
233 return EAXREVERB_ENVIRONMENTSIZE;
235 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
236 return EAXREVERB_ENVIRONMENTDIFFUSION;
238 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
239 return EAXREVERB_AIRABSORPTIONHF;
241 case DSPROPERTY_EAX20LISTENER_FLAGS:
242 return EAXREVERB_FLAGS;
244 default:
245 fail("Unsupported EAX 2.0 listener property id.");
249 ALuint EaxEaxCall::convert_eax_v2_0_buffer_property_id(
250 ALuint property_id)
252 switch (property_id)
254 case DSPROPERTY_EAX20BUFFER_NONE:
255 return EAXSOURCE_NONE;
257 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
258 return EAXSOURCE_ALLPARAMETERS;
260 case DSPROPERTY_EAX20BUFFER_DIRECT:
261 return EAXSOURCE_DIRECT;
263 case DSPROPERTY_EAX20BUFFER_DIRECTHF:
264 return EAXSOURCE_DIRECTHF;
266 case DSPROPERTY_EAX20BUFFER_ROOM:
267 return EAXSOURCE_ROOM;
269 case DSPROPERTY_EAX20BUFFER_ROOMHF:
270 return EAXSOURCE_ROOMHF;
272 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
273 return EAXSOURCE_ROOMROLLOFFFACTOR;
275 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
276 return EAXSOURCE_OBSTRUCTION;
278 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
279 return EAXSOURCE_OBSTRUCTIONLFRATIO;
281 case DSPROPERTY_EAX20BUFFER_OCCLUSION:
282 return EAXSOURCE_OCCLUSION;
284 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
285 return EAXSOURCE_OCCLUSIONLFRATIO;
287 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
288 return EAXSOURCE_OCCLUSIONROOMRATIO;
290 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
291 return EAXSOURCE_OUTSIDEVOLUMEHF;
293 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
294 return EAXSOURCE_AIRABSORPTIONFACTOR;
296 case DSPROPERTY_EAX20BUFFER_FLAGS:
297 return EAXSOURCE_FLAGS;
299 default:
300 fail("Unsupported EAX 2.0 buffer property id.");
305 EaxEaxCall create_eax_call(
306 bool is_get,
307 const GUID* property_set_id,
308 ALuint property_id,
309 ALuint property_source_id,
310 ALvoid* property_buffer,
311 ALuint property_size)
313 if(!property_set_id)
314 throw EaxEaxCallException{"Null property set ID."};
316 return EaxEaxCall{
317 is_get,
318 *property_set_id,
319 property_id,
320 property_source_id,
321 property_buffer,
322 property_size