1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
#include "config.h"
#include "al/eax_eax_call.h"
#include "al/eax_exception.h"
namespace {
constexpr auto deferred_flag = 0x80000000U;
class EaxEaxCallException :
public EaxException
{
public:
explicit EaxEaxCallException(
const char* message)
:
EaxException{"EAX_EAX_CALL", message}
{
}
}; // EaxEaxCallException
} // namespace
EaxEaxCall::EaxEaxCall(
bool is_get,
const GUID& property_set_guid,
ALuint property_id,
ALuint property_source_id,
ALvoid* property_buffer,
ALuint property_size)
: is_get_{is_get}, version_{0}, property_set_id_{EaxEaxCallPropertySetId::none}
, property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
, property_buffer_{property_buffer}, property_size_{property_size}
{
if (false)
{
}
else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
{
version_ = 4;
property_set_id_ = EaxEaxCallPropertySetId::context;
}
else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
{
version_ = 5;
property_set_id_ = EaxEaxCallPropertySetId::context;
}
else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
{
version_ = 2;
fx_slot_index_ = 0u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
property_id_ = convert_eax_v2_0_listener_property_id(property_id_);
}
else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
{
version_ = 3;
fx_slot_index_ = 0u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
}
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
{
version_ = 4;
fx_slot_index_ = 0u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
{
version_ = 5;
fx_slot_index_ = 0u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
{
version_ = 4;
fx_slot_index_ = 1u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
{
version_ = 5;
fx_slot_index_ = 1u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
{
version_ = 4;
fx_slot_index_ = 2u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
{
version_ = 5;
fx_slot_index_ = 2u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
{
version_ = 4;
fx_slot_index_ = 3u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
{
version_ = 5;
fx_slot_index_ = 3u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
}
else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
{
version_ = 2;
property_set_id_ = EaxEaxCallPropertySetId::source;
property_id_ = convert_eax_v2_0_buffer_property_id(property_id_);
}
else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
{
version_ = 3;
property_set_id_ = EaxEaxCallPropertySetId::source;
}
else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
{
version_ = 4;
property_set_id_ = EaxEaxCallPropertySetId::source;
}
else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
{
version_ = 5;
property_set_id_ = EaxEaxCallPropertySetId::source;
}
else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
{
version_ = 1;
fx_slot_index_ = 0u;
property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
}
else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
{
version_ = 1;
property_set_id_ = EaxEaxCallPropertySetId::source;
}
else
{
fail("Unsupported property set id.");
}
if (version_ < 1 || version_ > 5)
{
fail("EAX version out of range.");
}
if(!(property_id&deferred_flag))
{
if(property_set_id_ != EaxEaxCallPropertySetId::fx_slot && property_id_ != 0)
{
if (!property_buffer)
{
fail("Null property buffer.");
}
if (property_size == 0)
{
fail("Empty property.");
}
}
}
if(property_set_id_ == EaxEaxCallPropertySetId::source && property_source_id_ == 0)
{
fail("Null AL source id.");
}
if (property_set_id_ == EaxEaxCallPropertySetId::fx_slot)
{
if (property_id_ < EAXFXSLOT_NONE)
{
property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
}
}
}
[[noreturn]]
void EaxEaxCall::fail(
const char* message)
{
throw EaxEaxCallException{message};
}
ALuint EaxEaxCall::convert_eax_v2_0_listener_property_id(
ALuint property_id)
{
switch (property_id)
{
case DSPROPERTY_EAX20LISTENER_NONE:
return EAXREVERB_NONE;
case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
return EAXREVERB_ALLPARAMETERS;
case DSPROPERTY_EAX20LISTENER_ROOM:
return EAXREVERB_ROOM;
case DSPROPERTY_EAX20LISTENER_ROOMHF:
return EAXREVERB_ROOMHF;
case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
return EAXREVERB_ROOMROLLOFFFACTOR;
case DSPROPERTY_EAX20LISTENER_DECAYTIME:
return EAXREVERB_DECAYTIME;
case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
return EAXREVERB_DECAYHFRATIO;
case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
return EAXREVERB_REFLECTIONS;
case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
return EAXREVERB_REFLECTIONSDELAY;
case DSPROPERTY_EAX20LISTENER_REVERB:
return EAXREVERB_REVERB;
case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
return EAXREVERB_REVERBDELAY;
case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
return EAXREVERB_ENVIRONMENT;
case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
return EAXREVERB_ENVIRONMENTSIZE;
case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
return EAXREVERB_ENVIRONMENTDIFFUSION;
case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
return EAXREVERB_AIRABSORPTIONHF;
case DSPROPERTY_EAX20LISTENER_FLAGS:
return EAXREVERB_FLAGS;
default:
fail("Unsupported EAX 2.0 listener property id.");
}
}
ALuint EaxEaxCall::convert_eax_v2_0_buffer_property_id(
ALuint property_id)
{
switch (property_id)
{
case DSPROPERTY_EAX20BUFFER_NONE:
return EAXSOURCE_NONE;
case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
return EAXSOURCE_ALLPARAMETERS;
case DSPROPERTY_EAX20BUFFER_DIRECT:
return EAXSOURCE_DIRECT;
case DSPROPERTY_EAX20BUFFER_DIRECTHF:
return EAXSOURCE_DIRECTHF;
case DSPROPERTY_EAX20BUFFER_ROOM:
return EAXSOURCE_ROOM;
case DSPROPERTY_EAX20BUFFER_ROOMHF:
return EAXSOURCE_ROOMHF;
case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
return EAXSOURCE_ROOMROLLOFFFACTOR;
case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
return EAXSOURCE_OBSTRUCTION;
case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
return EAXSOURCE_OBSTRUCTIONLFRATIO;
case DSPROPERTY_EAX20BUFFER_OCCLUSION:
return EAXSOURCE_OCCLUSION;
case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
return EAXSOURCE_OCCLUSIONLFRATIO;
case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
return EAXSOURCE_OCCLUSIONROOMRATIO;
case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
return EAXSOURCE_OUTSIDEVOLUMEHF;
case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
return EAXSOURCE_AIRABSORPTIONFACTOR;
case DSPROPERTY_EAX20BUFFER_FLAGS:
return EAXSOURCE_FLAGS;
default:
fail("Unsupported EAX 2.0 buffer property id.");
}
}
EaxEaxCall create_eax_call(
bool is_get,
const GUID* property_set_id,
ALuint property_id,
ALuint property_source_id,
ALvoid* property_buffer,
ALuint property_size)
{
if(!property_set_id)
throw EaxEaxCallException{"Null property set ID."};
return EaxEaxCall{
is_get,
*property_set_id,
property_id,
property_source_id,
property_buffer,
property_size
};
}
|