1 /* DirectSound EAX interface
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "dsound_private.h"
26 #include "eax-presets.h"
33 static EAXOBSTRUCTIONPROPERTIES
EAXSourceObstruction(const EAXSOURCEPROPERTIES
*props
)
35 EAXOBSTRUCTIONPROPERTIES ret
;
36 ret
.lObstruction
= props
->lObstruction
;
37 ret
.flObstructionLFRatio
= props
->flObstructionLFRatio
;
41 static EAXOCCLUSIONPROPERTIES
EAXSourceOcclusion(const EAXSOURCEPROPERTIES
*props
)
43 EAXOCCLUSIONPROPERTIES ret
;
44 ret
.lOcclusion
= props
->lOcclusion
;
45 ret
.flOcclusionLFRatio
= props
->flOcclusionLFRatio
;
46 ret
.flOcclusionRoomRatio
= props
->flOcclusionRoomRatio
;
47 ret
.flOcclusionDirectRatio
= props
->flOcclusionDirectRatio
;
51 static EAXEXCLUSIONPROPERTIES
EAXSourceExclusion(const EAXSOURCEPROPERTIES
*props
)
53 EAXEXCLUSIONPROPERTIES ret
;
54 ret
.lExclusion
= props
->lExclusion
;
55 ret
.flExclusionLFRatio
= props
->flExclusionLFRatio
;
59 HRESULT
EAX3_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
61 if(prim
->effect
[0] == 0)
62 return E_PROP_ID_UNSUPPORTED
;
64 switch((propid
&~DSPROPERTY_EAX30LISTENER_DEFERRED
))
66 case DSPROPERTY_EAX30LISTENER_NONE
:
67 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
68 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
69 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
70 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
71 case DSPROPERTY_EAX30LISTENER_ROOM
:
72 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
73 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
74 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
75 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
76 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
77 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
78 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
79 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
80 case DSPROPERTY_EAX30LISTENER_REVERB
:
81 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
82 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
83 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
84 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
85 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
86 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
87 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
88 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
89 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
90 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
91 case DSPROPERTY_EAX30LISTENER_FLAGS
:
92 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
95 FIXME("Unhandled propid: 0x%08lx\n", propid
);
96 return E_PROP_ID_UNSUPPORTED
;
99 HRESULT
EAX3_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
101 /* Should this be using slot 0 or the primary slot? */
102 if(prim
->effect
[0] == 0)
103 return E_PROP_ID_UNSUPPORTED
;
104 if(prim
->deferred
.fxslot
[0].effect_type
!= FXSLOT_EFFECT_REVERB
)
106 ERR("Trying to set reverb parameters on non-reverb slot\n");
107 return DSERR_INVALIDCALL
;
112 case DSPROPERTY_EAX30LISTENER_NONE
: /* not setting any property, just applying */
115 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
116 if(cbPropData
>= sizeof(EAX30LISTENERPROPERTIES
))
118 /* Ensure compatible types (should generate a warning if not). */
119 union { void *v
; EAX30LISTENERPROPERTIES
*props
; } data
= { pPropData
};
120 EAXREVERBPROPERTIES
*revprops
= data
.props
;
121 return EAXReverb_Set(prim
, 0, EAXREVERB_ALLPARAMETERS
, revprops
, cbPropData
);
123 return DSERR_INVALIDPARAM
;
125 #define HANDLE_PROP(P) case DSPROPERTY_EAX30LISTENER_##P: \
126 return EAXReverb_Set(prim, 0, EAXREVERB_##P, pPropData, cbPropData);
127 HANDLE_PROP(ENVIRONMENT
)
128 HANDLE_PROP(ENVIRONMENTSIZE
)
129 HANDLE_PROP(ENVIRONMENTDIFFUSION
)
133 HANDLE_PROP(DECAYTIME
)
134 HANDLE_PROP(DECAYHFRATIO
)
135 HANDLE_PROP(DECAYLFRATIO
)
136 HANDLE_PROP(REFLECTIONS
)
137 HANDLE_PROP(REFLECTIONSDELAY
)
138 HANDLE_PROP(REFLECTIONSPAN
)
140 HANDLE_PROP(REVERBDELAY
)
141 HANDLE_PROP(REVERBPAN
)
142 HANDLE_PROP(ECHOTIME
)
143 HANDLE_PROP(ECHODEPTH
)
144 HANDLE_PROP(MODULATIONTIME
)
145 HANDLE_PROP(MODULATIONDEPTH
)
146 HANDLE_PROP(AIRABSORPTIONHF
)
147 HANDLE_PROP(HFREFERENCE
)
148 HANDLE_PROP(LFREFERENCE
)
149 HANDLE_PROP(ROOMROLLOFFFACTOR
)
153 FIXME("Unhandled propid: 0x%08lx\n", propid
);
154 return DSERR_INVALIDPARAM
;
157 #define GET_PROP(src, T) do { \
158 if(cbPropData >= sizeof(T)) \
160 union { void *v; T *props; } data = { pPropData }; \
162 *pcbReturned = sizeof(T); \
165 return DSERR_INVALIDPARAM; \
168 HRESULT
EAX3_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
170 if(prim
->effect
[0] == 0)
171 return E_PROP_ID_UNSUPPORTED
;
172 if(prim
->deferred
.fxslot
[0].effect_type
!= FXSLOT_EFFECT_REVERB
)
174 ERR("Trying to get reverb parameters on non-reverb slot\n");
175 return DSERR_INVALIDCALL
;
180 case DSPROPERTY_EAX30LISTENER_NONE
:
184 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
185 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
, EAX30LISTENERPROPERTIES
);
186 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
187 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.dwEnvironment
, DWORD
);
188 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
189 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flEnvironmentSize
, float);
190 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
191 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flEnvironmentDiffusion
, float);
192 case DSPROPERTY_EAX30LISTENER_ROOM
:
193 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lRoom
, long);
194 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
195 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lRoomHF
, long);
196 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
197 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lRoomLF
, long);
198 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
199 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flDecayTime
, float);
200 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
201 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flDecayHFRatio
, float);
202 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
203 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flDecayLFRatio
, float);
204 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
205 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lReflections
, long);
206 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
207 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flReflectionsDelay
, float);
208 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
209 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.vReflectionsPan
, EAXVECTOR
);
210 case DSPROPERTY_EAX30LISTENER_REVERB
:
211 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lReverb
, long);
212 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
213 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flReverbDelay
, float);
214 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
215 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.vReverbPan
, EAXVECTOR
);
216 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
217 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flEchoTime
, float);
218 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
219 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flEchoDepth
, float);
220 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
221 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flModulationTime
, float);
222 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
223 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flModulationDepth
, float);
224 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
225 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flAirAbsorptionHF
, float);
226 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
227 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flHFReference
, float);
228 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
229 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flLFReference
, float);
230 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
231 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flRoomRolloffFactor
, float);
232 case DSPROPERTY_EAX30LISTENER_FLAGS
:
233 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.dwFlags
, DWORD
);
235 FIXME("Unhandled propid: 0x%08lx\n", propid
);
236 return DSERR_INVALIDPARAM
;
240 HRESULT
EAX3Buffer_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
244 switch((propid
&~DSPROPERTY_EAX30BUFFER_DEFERRED
))
246 case DSPROPERTY_EAX30BUFFER_NONE
:
247 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
248 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS
:
249 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS
:
250 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS
:
251 case DSPROPERTY_EAX30BUFFER_DIRECT
:
252 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
253 case DSPROPERTY_EAX30BUFFER_ROOM
:
254 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
255 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
256 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
257 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
258 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
259 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
260 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
261 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
262 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
263 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
264 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR
:
265 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR
:
266 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
267 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
268 case DSPROPERTY_EAX30BUFFER_FLAGS
:
269 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
272 FIXME("Unhandled propid: 0x%08lx\n", propid
);
273 return E_PROP_ID_UNSUPPORTED
;
277 HRESULT
EAX3Buffer_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
281 case DSPROPERTY_EAX30BUFFER_NONE
: /* not setting any property, just applying */
284 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
285 if(cbPropData
>= sizeof(EAX30BUFFERPROPERTIES
))
287 /* Ensure compatible types (should generate a warning if not). */
288 union { void *v
; EAX30BUFFERPROPERTIES
*props
; } data
= { pPropData
};
289 EAXSOURCEPROPERTIES
*srcprops
= data
.props
;
290 return EAX4Source_Set(buf
, EAXSOURCE_ALLPARAMETERS
, srcprops
, cbPropData
);
292 return DSERR_INVALIDPARAM
;
294 #define HANDLE_PROP(P) case DSPROPERTY_EAX30BUFFER_##P: \
295 return EAX4Source_Set(buf, EAXSOURCE_##P, pPropData, cbPropData);
296 HANDLE_PROP(OBSTRUCTIONPARAMETERS
)
297 HANDLE_PROP(OCCLUSIONPARAMETERS
)
298 HANDLE_PROP(EXCLUSIONPARAMETERS
)
300 HANDLE_PROP(DIRECTHF
)
303 HANDLE_PROP(OBSTRUCTION
)
304 HANDLE_PROP(OBSTRUCTIONLFRATIO
)
305 HANDLE_PROP(OCCLUSION
)
306 HANDLE_PROP(OCCLUSIONLFRATIO
)
307 HANDLE_PROP(OCCLUSIONROOMRATIO
)
308 HANDLE_PROP(OCCLUSIONDIRECTRATIO
)
309 HANDLE_PROP(EXCLUSION
)
310 HANDLE_PROP(EXCLUSIONLFRATIO
)
311 HANDLE_PROP(OUTSIDEVOLUMEHF
)
312 HANDLE_PROP(DOPPLERFACTOR
)
313 HANDLE_PROP(ROLLOFFFACTOR
)
314 HANDLE_PROP(ROOMROLLOFFFACTOR
)
315 HANDLE_PROP(AIRABSORPTIONFACTOR
)
319 FIXME("Unhandled propid: 0x%08lx\n", propid
);
320 return E_PROP_ID_UNSUPPORTED
;
323 HRESULT
EAX3Buffer_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
327 case DSPROPERTY_EAX30BUFFER_NONE
:
331 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
332 GET_PROP(buf
->current
.eax
, EAX30BUFFERPROPERTIES
);
333 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS
:
334 GET_PROP(EAXSourceObstruction(&buf
->current
.eax
), EAXOBSTRUCTIONPROPERTIES
);
335 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS
:
336 GET_PROP(EAXSourceOcclusion(&buf
->current
.eax
), EAXOCCLUSIONPROPERTIES
);
337 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS
:
338 GET_PROP(EAXSourceExclusion(&buf
->current
.eax
), EAXEXCLUSIONPROPERTIES
);
339 case DSPROPERTY_EAX30BUFFER_DIRECT
:
340 GET_PROP(buf
->current
.eax
.lDirect
, long);
341 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
342 GET_PROP(buf
->current
.eax
.lDirectHF
, long);
343 case DSPROPERTY_EAX30BUFFER_ROOM
:
344 GET_PROP(buf
->current
.eax
.lRoom
, long);
345 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
346 GET_PROP(buf
->current
.eax
.lRoomHF
, long);
347 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
348 GET_PROP(buf
->current
.eax
.lObstruction
, long);
349 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
350 GET_PROP(buf
->current
.eax
.flObstructionLFRatio
, float);
351 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
352 GET_PROP(buf
->current
.eax
.lOcclusion
, long);
353 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
354 GET_PROP(buf
->current
.eax
.flOcclusionLFRatio
, float);
355 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
356 GET_PROP(buf
->current
.eax
.flOcclusionRoomRatio
, float);
357 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
358 GET_PROP(buf
->current
.eax
.flOcclusionDirectRatio
, float);
359 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
360 GET_PROP(buf
->current
.eax
.lExclusion
, long);
361 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
362 GET_PROP(buf
->current
.eax
.flExclusionLFRatio
, float);
363 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
364 GET_PROP(buf
->current
.eax
.lOutsideVolumeHF
, long);
365 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR
:
366 GET_PROP(buf
->current
.eax
.flDopplerFactor
, float);
367 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR
:
368 GET_PROP(buf
->current
.eax
.flRolloffFactor
, float);
369 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
370 GET_PROP(buf
->current
.eax
.flRoomRolloffFactor
, float);
371 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
372 GET_PROP(buf
->current
.eax
.flAirAbsorptionFactor
, float);
373 case DSPROPERTY_EAX30BUFFER_FLAGS
:
374 GET_PROP(buf
->current
.eax
.dwFlags
, DWORD
);
376 FIXME("Unhandled propid: 0x%08lx\n", propid
);
377 return DSERR_INVALIDPARAM
;
385 #define EAX2LISTENERFLAGS_MASK (EAX20LISTENERFLAGS_DECAYTIMESCALE | \
386 EAX20LISTENERFLAGS_REFLECTIONSSCALE | \
387 EAX20LISTENERFLAGS_REFLECTIONSDELAYSCALE | \
388 EAX20LISTENERFLAGS_REVERBSCALE | \
389 EAX20LISTENERFLAGS_REVERBDELAYSCALE | \
390 EAX20LISTENERFLAGS_DECAYHFLIMIT)
392 static EAX20LISTENERPROPERTIES
EAXRevTo2(const EAXREVERBPROPERTIES
*props
)
394 EAX20LISTENERPROPERTIES ret
;
395 ret
.lRoom
= props
->lRoom
;
396 ret
.lRoomHF
= props
->lRoomHF
;
397 ret
.flRoomRolloffFactor
= props
->flRoomRolloffFactor
;
398 ret
.flDecayTime
= props
->flDecayTime
;
399 ret
.flDecayHFRatio
= props
->flDecayHFRatio
;
400 ret
.lReflections
= props
->lReflections
;
401 ret
.flReflectionsDelay
= props
->flReflectionsDelay
;
402 ret
.lReverb
= props
->lReverb
;
403 ret
.flReverbDelay
= props
->flReverbDelay
;
404 ret
.dwEnvironment
= props
->dwEnvironment
;
405 ret
.flEnvironmentSize
= props
->flEnvironmentSize
;
406 ret
.flEnvironmentDiffusion
= props
->flEnvironmentDiffusion
;
407 ret
.flAirAbsorptionHF
= props
->flAirAbsorptionHF
;
408 ret
.dwFlags
= props
->dwFlags
& EAX2LISTENERFLAGS_MASK
;
412 static EAX20BUFFERPROPERTIES
EAXSourceTo2(const EAXSOURCEPROPERTIES
*props
)
414 EAX20BUFFERPROPERTIES ret
;
415 ret
.lDirect
= props
->lDirect
;
416 ret
.lDirectHF
= props
->lDirectHF
;
417 ret
.lRoom
= props
->lRoom
;
418 ret
.lRoomHF
= props
->lRoomHF
;
419 ret
.flRoomRolloffFactor
= props
->flRoomRolloffFactor
;
420 ret
.lObstruction
= props
->lObstruction
;
421 ret
.flObstructionLFRatio
= props
->flObstructionLFRatio
;
422 ret
.lOcclusion
= props
->lOcclusion
;
423 ret
.flOcclusionLFRatio
= props
->flOcclusionLFRatio
;
424 ret
.flOcclusionRoomRatio
= props
->flOcclusionRoomRatio
;
425 ret
.lOutsideVolumeHF
= props
->lOutsideVolumeHF
;
426 ret
.flAirAbsorptionFactor
= props
->flAirAbsorptionFactor
;
427 ret
.dwFlags
= props
->dwFlags
;
432 HRESULT
EAX2_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
434 if(prim
->effect
[0] == 0)
435 return E_PROP_ID_UNSUPPORTED
;
437 switch((propid
&~DSPROPERTY_EAX20LISTENER_DEFERRED
))
439 case DSPROPERTY_EAX20LISTENER_NONE
:
440 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
441 case DSPROPERTY_EAX20LISTENER_ROOM
:
442 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
443 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
444 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
445 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
446 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
447 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
448 case DSPROPERTY_EAX20LISTENER_REVERB
:
449 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
450 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
451 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
452 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
453 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
454 case DSPROPERTY_EAX20LISTENER_FLAGS
:
455 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
458 FIXME("Unhandled propid: 0x%08lx\n", propid
);
459 return E_PROP_ID_UNSUPPORTED
;
462 HRESULT
EAX2_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
464 if(prim
->effect
[0] == 0)
465 return E_PROP_ID_UNSUPPORTED
;
466 if(prim
->deferred
.fxslot
[0].effect_type
!= FXSLOT_EFFECT_REVERB
)
468 ERR("Trying to set reverb parameters on non-reverb slot\n");
469 return DSERR_INVALIDCALL
;
474 case DSPROPERTY_EAX20LISTENER_NONE
: /* not setting any property, just applying */
477 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
478 if(cbPropData
>= sizeof(EAX20LISTENERPROPERTIES
))
482 const EAX20LISTENERPROPERTIES
*props
;
483 } data
= { pPropData
};
484 EAXREVERBPROPERTIES props
= REVERB_PRESET_GENERIC
;
485 TRACE("Parameters:\n\tEnvironment: %lu\n\tEnvSize: %f\n\tEnvDiffusion: %f\n\t"
486 "Room: %ld\n\tRoom HF: %ld\n\tDecay Time: %f\n\tDecay HF Ratio: %f\n\t"
487 "Reflections: %ld\n\tReflections Delay: %f\n\tReverb: %ld\n\tReverb Delay: %f\n\t"
488 "Air Absorption: %f\n\tRoom Rolloff: %f\n\tFlags: 0x%02lx\n",
489 data
.props
->dwEnvironment
, data
.props
->flEnvironmentSize
,
490 data
.props
->flEnvironmentDiffusion
, data
.props
->lRoom
, data
.props
->lRoomHF
,
491 data
.props
->flDecayTime
, data
.props
->flDecayHFRatio
, data
.props
->lReflections
,
492 data
.props
->flReflectionsDelay
, data
.props
->lReverb
, data
.props
->flReverbDelay
,
493 data
.props
->flAirAbsorptionHF
, data
.props
->flRoomRolloffFactor
, data
.props
->dwFlags
496 if(data
.props
->dwEnvironment
< EAX_ENVIRONMENT_UNDEFINED
)
498 props
= EnvironmentDefaults
[data
.props
->dwEnvironment
];
499 props
.dwEnvironment
= data
.props
->dwEnvironment
;
501 props
.flEnvironmentSize
= data
.props
->flEnvironmentSize
;
502 props
.flEnvironmentDiffusion
= data
.props
->flEnvironmentDiffusion
;
503 props
.lRoom
= data
.props
->lRoom
;
504 props
.lRoomHF
= data
.props
->lRoomHF
;
505 props
.flDecayTime
= data
.props
->flDecayTime
;
506 props
.flDecayHFRatio
= data
.props
->flDecayHFRatio
;
507 props
.lReflections
= data
.props
->lReflections
;
508 props
.flReflectionsDelay
= data
.props
->flReflectionsDelay
;
509 props
.lReverb
= data
.props
->lReverb
;
510 props
.flReverbDelay
= data
.props
->flReverbDelay
;
511 props
.flAirAbsorptionHF
= data
.props
->flAirAbsorptionHF
;
512 props
.flRoomRolloffFactor
= data
.props
->flRoomRolloffFactor
;
513 props
.dwFlags
= data
.props
->dwFlags
;
514 return EAXReverb_Set(prim
, 0, EAXREVERB_ALLPARAMETERS
, &props
, sizeof(props
));
516 return DSERR_INVALIDPARAM
;
518 #define HANDLE_PROP(P) case DSPROPERTY_EAX20LISTENER_##P: \
519 return EAXReverb_Set(prim, 0, EAXREVERB_##P, pPropData, cbPropData);
522 HANDLE_PROP(DECAYTIME
)
523 HANDLE_PROP(DECAYHFRATIO
)
524 HANDLE_PROP(REFLECTIONS
)
525 HANDLE_PROP(REFLECTIONSDELAY
)
527 HANDLE_PROP(REVERBDELAY
)
528 HANDLE_PROP(ENVIRONMENT
)
529 HANDLE_PROP(ENVIRONMENTSIZE
)
530 HANDLE_PROP(ENVIRONMENTDIFFUSION
)
531 HANDLE_PROP(AIRABSORPTIONHF
)
532 HANDLE_PROP(ROOMROLLOFFFACTOR
)
536 FIXME("Unhandled propid: 0x%08lx\n", propid
);
537 return E_PROP_ID_UNSUPPORTED
;
540 HRESULT
EAX2_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
542 if(prim
->effect
[0] == 0)
543 return E_PROP_ID_UNSUPPORTED
;
544 if(prim
->deferred
.fxslot
[0].effect_type
!= FXSLOT_EFFECT_REVERB
)
546 ERR("Trying to get reverb parameters on non-reverb slot\n");
547 return DSERR_INVALIDCALL
;
552 case DSPROPERTY_EAX20LISTENER_NONE
:
556 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
557 GET_PROP(EAXRevTo2(&prim
->deferred
.fxslot
[0].fx
.reverb
), EAX20LISTENERPROPERTIES
);
558 case DSPROPERTY_EAX20LISTENER_ROOM
:
559 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lRoom
, long);
560 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
561 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lRoomHF
, long);
562 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
563 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flRoomRolloffFactor
, float);
564 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
565 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flDecayTime
, float);
566 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
567 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flDecayHFRatio
, float);
568 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
569 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lReflections
, long);
570 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
571 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flReflectionsDelay
, float);
572 case DSPROPERTY_EAX20LISTENER_REVERB
:
573 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.lReverb
, long);
574 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
575 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flReverbDelay
, float);
576 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
577 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.dwEnvironment
, DWORD
);
578 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
579 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flEnvironmentSize
, float);
580 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
581 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flEnvironmentDiffusion
, float);
582 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
583 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.flAirAbsorptionHF
, float);
584 case DSPROPERTY_EAX20LISTENER_FLAGS
:
585 GET_PROP(prim
->deferred
.fxslot
[0].fx
.reverb
.dwFlags
&EAX2LISTENERFLAGS_MASK
, DWORD
);
587 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
588 return E_PROP_ID_UNSUPPORTED
;
592 HRESULT
EAX2Buffer_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
596 switch((propid
&~DSPROPERTY_EAX20BUFFER_DEFERRED
))
598 case DSPROPERTY_EAX20BUFFER_NONE
:
599 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
600 case DSPROPERTY_EAX20BUFFER_DIRECT
:
601 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
602 case DSPROPERTY_EAX20BUFFER_ROOM
:
603 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
604 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
605 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
606 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
607 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
608 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
609 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
610 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
611 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
612 case DSPROPERTY_EAX20BUFFER_FLAGS
:
613 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
616 FIXME("Unhandled propid: 0x%08lx\n", propid
);
617 return E_PROP_ID_UNSUPPORTED
;
620 HRESULT
EAX2Buffer_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
624 case DSPROPERTY_EAX20BUFFER_NONE
: /* not setting any property, just applying */
627 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
628 if(cbPropData
>= sizeof(EAX20BUFFERPROPERTIES
))
632 const EAX20BUFFERPROPERTIES
*props
;
633 } data
= { pPropData
};
634 EAXSOURCEPROPERTIES props
;
635 TRACE("Parameters:\n\tDirect: %ld\n\tDirect HF: %ld\n\tRoom: %ld\n\tRoom HF: %ld\n\t"
636 "Room Rolloff Factor: %f\n\tObstruction: %ld\n\tObstruction LF Ratio: %f\n\t"
637 "Occlusion: %ld\n\tOcclusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
638 "Outside Volume HF: %ld\n\tAir Absorb Factor: %f\n\tFlags: 0x%02lx\n",
639 data
.props
->lDirect
, data
.props
->lDirectHF
, data
.props
->lRoom
, data
.props
->lRoomHF
,
640 data
.props
->flRoomRolloffFactor
, data
.props
->lObstruction
,
641 data
.props
->flObstructionLFRatio
, data
.props
->lOcclusion
,
642 data
.props
->flOcclusionLFRatio
, data
.props
->flOcclusionRoomRatio
,
643 data
.props
->lOutsideVolumeHF
, data
.props
->flAirAbsorptionFactor
,
647 props
= buf
->deferred
.eax
;
648 props
.lDirect
= data
.props
->lDirect
;
649 props
.lDirectHF
= data
.props
->lDirectHF
;
650 props
.lRoom
= data
.props
->lRoom
;
651 props
.lRoomHF
= data
.props
->lRoomHF
;
652 props
.flRoomRolloffFactor
= data
.props
->flRoomRolloffFactor
;
653 props
.lObstruction
= data
.props
->lObstruction
;
654 props
.flObstructionLFRatio
= data
.props
->flObstructionLFRatio
;
655 props
.lOcclusion
= data
.props
->lOcclusion
;
656 props
.flOcclusionLFRatio
= data
.props
->flOcclusionLFRatio
;
657 props
.flOcclusionRoomRatio
= data
.props
->flOcclusionRoomRatio
+ 1.0f
;
658 props
.lOutsideVolumeHF
= data
.props
->lOutsideVolumeHF
;
659 props
.flAirAbsorptionFactor
= data
.props
->flAirAbsorptionFactor
;
660 props
.dwFlags
= data
.props
->dwFlags
;
661 return EAX4Source_Set(buf
, EAXSOURCE_ALLPARAMETERS
, &props
, sizeof(props
));
663 return DSERR_INVALIDPARAM
;
665 /* Special-case occlusion room ratio, since its behavior changed with EAX3
668 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
669 if(cbPropData
>= sizeof(float))
671 union { const void *v
; const float *fl
; } data
= { pPropData
};
672 float f
= *data
.fl
+ 1.0f
;
673 return EAX4Source_Set(buf
, EAXSOURCE_OCCLUSIONROOMRATIO
, &f
, sizeof(f
));
675 return DSERR_INVALIDPARAM
;
677 #define HANDLE_PROP(P) case DSPROPERTY_EAX20BUFFER_##P: \
678 return EAX4Source_Set(buf, EAXSOURCE_##P, pPropData, cbPropData);
680 HANDLE_PROP(DIRECTHF
)
683 HANDLE_PROP(OBSTRUCTION
)
684 HANDLE_PROP(OBSTRUCTIONLFRATIO
)
685 HANDLE_PROP(OCCLUSION
)
686 HANDLE_PROP(OCCLUSIONLFRATIO
)
687 HANDLE_PROP(OUTSIDEVOLUMEHF
)
688 HANDLE_PROP(ROOMROLLOFFFACTOR
)
689 HANDLE_PROP(AIRABSORPTIONFACTOR
)
693 FIXME("Unhandled propid: 0x%08lx\n", propid
);
694 return E_PROP_ID_UNSUPPORTED
;
697 HRESULT
EAX2Buffer_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
701 case DSPROPERTY_EAX20BUFFER_NONE
:
705 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
706 GET_PROP(EAXSourceTo2(&buf
->current
.eax
), EAX20BUFFERPROPERTIES
);
707 case DSPROPERTY_EAX20BUFFER_DIRECT
:
708 GET_PROP(buf
->current
.eax
.lDirect
, long);
709 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
710 GET_PROP(buf
->current
.eax
.lDirectHF
, long);
711 case DSPROPERTY_EAX20BUFFER_ROOM
:
712 GET_PROP(buf
->current
.eax
.lRoom
, long);
713 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
714 GET_PROP(buf
->current
.eax
.lRoomHF
, long);
715 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
716 GET_PROP(buf
->current
.eax
.flRoomRolloffFactor
, float);
717 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
718 GET_PROP(buf
->current
.eax
.lObstruction
, long);
719 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
720 GET_PROP(buf
->current
.eax
.flObstructionLFRatio
, float);
721 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
722 GET_PROP(buf
->current
.eax
.lOcclusion
, long);
723 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
724 GET_PROP(buf
->current
.eax
.flOcclusionLFRatio
, float);
725 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
726 GET_PROP(maxF(buf
->current
.eax
.flOcclusionRoomRatio
-1.0f
, 0.0f
), float);
727 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
728 GET_PROP(buf
->current
.eax
.lOutsideVolumeHF
, long);
729 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
730 GET_PROP(buf
->current
.eax
.flAirAbsorptionFactor
, float);
731 case DSPROPERTY_EAX20BUFFER_FLAGS
:
732 GET_PROP(buf
->current
.eax
.dwFlags
, DWORD
);
734 FIXME("Unhandled propid: 0x%08lx\n", propid
);
735 return E_PROP_ID_UNSUPPORTED
;
743 HRESULT
EAX1_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
745 if(prim
->effect
[0] == 0)
746 return E_PROP_ID_UNSUPPORTED
;
750 case DSPROPERTY_EAX10LISTENER_ALL
:
751 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT
:
752 case DSPROPERTY_EAX10LISTENER_VOLUME
:
753 case DSPROPERTY_EAX10LISTENER_DECAYTIME
:
754 case DSPROPERTY_EAX10LISTENER_DAMPING
:
755 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
758 FIXME("Unhandled propid: 0x%08lx\n", propid
);
759 return E_PROP_ID_UNSUPPORTED
;
762 HRESULT
EAX1_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
764 static const float eax1_env_volume
[EAX_ENVIRONMENT_UNDEFINED
] = {
765 0.5f
, 0.25f
, 0.417f
, 0.653f
, 0.208f
, 0.5f
, 0.403f
, 0.5f
, 0.5f
,
766 0.361f
, 0.5f
, 0.153f
, 0.361f
, 0.444f
, 0.25f
, 0.111f
, 0.111f
,
767 0.194f
, 1.0f
, 0.097f
, 0.208f
, 0.652f
, 1.0f
, 0.875f
, 0.139f
, 0.486f
769 static const float eax1_env_dampening
[EAX_ENVIRONMENT_UNDEFINED
] = {
770 0.5f
, 0.0f
, 0.666f
, 0.166f
, 0.0f
, 0.888f
, 0.5f
, 0.5f
, 1.304f
,
771 0.332f
, 0.3f
, 2.0f
, 0.0f
, 0.638f
, 0.776f
, 0.472f
, 0.224f
, 0.472f
,
772 0.5f
, 0.224f
, 1.5f
, 0.25f
, 0.0f
, 1.388f
, 0.666f
, 0.806f
776 if(prim
->effect
[0] == 0)
777 return E_PROP_ID_UNSUPPORTED
;
778 if(prim
->deferred
.fxslot
[0].effect_type
!= FXSLOT_EFFECT_REVERB
)
780 ERR("Trying to set reverb parameters on non-reverb slot\n");
781 return DSERR_INVALIDCALL
;
786 case DSPROPERTY_EAX10LISTENER_ALL
:
787 if(cbPropData
>= sizeof(EAX10LISTENERPROPERTIES
))
791 const EAX10LISTENERPROPERTIES
*props
;
792 } data
= { pPropData
};
793 TRACE("Parameters:\n\tEnvironment: %lu\n\tVolume: %f\n\tDecay Time: %f\n\t"
794 "Damping: %f\n", data
.props
->dwEnvironment
, data
.props
->fVolume
,
795 data
.props
->fDecayTime
, data
.props
->fDamping
798 if(data
.props
->dwEnvironment
< EAX_ENVIRONMENT_UNDEFINED
)
800 /* NOTE: I'm not quite sure how to handle the volume. It's
801 * important to deal with since it can have a notable impact on
802 * the output levels, but given the default EAX1 environment
803 * volumes, they don't align with the gain/room volume for
804 * EAX2+ environments. Presuming the default volumes are
805 * correct, it's possible the reverb implementation was
806 * different and relied on different gains to get the intended
809 * Rather than just blindly applying the volume, we take the
810 * difference from the EAX1 environment's default volume and
811 * apply that as an offset to the EAX2 environment's volume.
813 EAXREVERBPROPERTIES env
= EnvironmentDefaults
[data
.props
->dwEnvironment
];
814 long db_vol
= clampI(
815 gain_to_mB(data
.props
->fVolume
/ eax1_env_volume
[data
.props
->dwEnvironment
]),
818 env
.lRoom
= clampI(env
.lRoom
+ db_vol
, -10000, 0);
819 env
.flDecayTime
= data
.props
->fDecayTime
;
821 hr
= EAXReverb_Set(prim
, 0, EAXREVERB_ALLPARAMETERS
, &env
, sizeof(env
));
824 prim
->deferred
.eax1_volume
= data
.props
->fVolume
;
825 prim
->deferred
.eax1_dampening
= data
.props
->fDamping
;
830 return DSERR_INVALIDPARAM
;
832 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT
:
833 hr
= EAXReverb_Set(prim
, 0, EAXREVERB_ENVIRONMENT
, pPropData
, cbPropData
);
836 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
837 prim
->deferred
.eax1_volume
= eax1_env_volume
[*data
.dw
];
838 prim
->deferred
.eax1_dampening
= eax1_env_dampening
[*data
.dw
];
842 case DSPROPERTY_EAX10LISTENER_VOLUME
:
843 if(cbPropData
>= sizeof(float))
845 union { const void *v
; const float *fl
; } data
= { pPropData
};
846 long db_vol
= clampI(
847 gain_to_mB(*data
.fl
/ eax1_env_volume
[prim
->deferred
.fxslot
[0].fx
.reverb
.dwEnvironment
]),
850 long room_vol
= clampI(
851 EnvironmentDefaults
[prim
->deferred
.fxslot
[0].fx
.reverb
.dwEnvironment
].lRoom
+ db_vol
,
854 TRACE("Volume: %f\n", *data
.fl
);
856 hr
= EAXReverb_Set(prim
, 0, EAXREVERB_ROOM
, &room_vol
, sizeof(room_vol
));
857 if(SUCCEEDED(hr
)) prim
->deferred
.eax1_volume
= *data
.fl
;
860 return DSERR_INVALIDPARAM
;
861 case DSPROPERTY_EAX10LISTENER_DECAYTIME
:
862 return EAXReverb_Set(prim
, 0, EAXREVERB_DECAYTIME
, pPropData
, cbPropData
);
863 case DSPROPERTY_EAX10LISTENER_DAMPING
:
864 if(cbPropData
>= sizeof(float))
866 union { const void *v
; const float *fl
; } data
= { pPropData
};
867 TRACE("Damping: %f\n", *data
.fl
);
869 prim
->deferred
.eax1_dampening
= *data
.fl
;
872 return DSERR_INVALIDPARAM
;
874 FIXME("Unhandled propid: 0x%08lx\n", propid
);
875 return E_PROP_ID_UNSUPPORTED
;
878 HRESULT
EAX1_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
880 if(prim
->effect
[0] == 0)
881 return E_PROP_ID_UNSUPPORTED
;
882 if(prim
->deferred
.fxslot
[0].effect_type
!= FXSLOT_EFFECT_REVERB
)
884 ERR("Trying to get reverb parameters on non-reverb slot\n");
885 return DSERR_INVALIDCALL
;
890 case DSPROPERTY_EAX10LISTENER_ALL
:
891 if(cbPropData
>= sizeof(EAX10LISTENERPROPERTIES
))
895 EAX10LISTENERPROPERTIES
*props
;
896 } data
= { pPropData
};
898 data
.props
->dwEnvironment
= prim
->deferred
.fxslot
[0].fx
.reverb
.dwEnvironment
;
899 data
.props
->fVolume
= prim
->deferred
.eax1_volume
;
900 data
.props
->fDecayTime
= prim
->deferred
.fxslot
[0].fx
.reverb
.flDecayTime
;
901 data
.props
->fDamping
= prim
->deferred
.eax1_dampening
;
903 *pcbReturned
= sizeof(EAX10LISTENERPROPERTIES
);
906 return DSERR_INVALIDPARAM
;
908 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT
:
909 return EAXReverb_Get(prim
, 0, EAXREVERB_ENVIRONMENT
, pPropData
, cbPropData
, pcbReturned
);
911 case DSPROPERTY_EAX10LISTENER_VOLUME
:
912 if(cbPropData
>= sizeof(float))
914 union { void *v
; float *fl
; } data
= { pPropData
};
915 *data
.fl
= prim
->deferred
.eax1_volume
;
916 *pcbReturned
= sizeof(float);
919 return DSERR_INVALIDPARAM
;
921 case DSPROPERTY_EAX10LISTENER_DECAYTIME
:
922 return EAXReverb_Get(prim
, 0, EAXREVERB_DECAYTIME
, pPropData
, cbPropData
, pcbReturned
);
924 case DSPROPERTY_EAX10LISTENER_DAMPING
:
925 if(cbPropData
>= sizeof(float))
927 union { void *v
; float *fl
; } data
= { pPropData
};
928 *data
.fl
= prim
->deferred
.eax1_dampening
;
929 *pcbReturned
= sizeof(float);
932 return DSERR_INVALIDPARAM
;
934 FIXME("Unhandled propid: 0x%08lx\n", propid
);
935 return E_PROP_ID_UNSUPPORTED
;
939 HRESULT
EAX1Buffer_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
945 case DSPROPERTY_EAX10BUFFER_ALL
:
946 case DSPROPERTY_EAX10BUFFER_REVERBMIX
:
947 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
950 FIXME("Unhandled propid: 0x%08lx\n", propid
);
951 return E_PROP_ID_UNSUPPORTED
;
954 HRESULT
EAX1Buffer_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
958 /* NOTE: DSPROPERTY_EAX10BUFFER_ALL is for EAX10BUFFERPROPERTIES, however
959 * that struct just contains the single ReverbMix float property.
961 case DSPROPERTY_EAX10BUFFER_ALL
:
962 case DSPROPERTY_EAX10BUFFER_REVERBMIX
:
963 if(cbPropData
>= sizeof(float))
965 union { const void *v
; const float *fl
; } data
= { pPropData
};
969 TRACE("Reverb Mix: %f\n", *data
.fl
);
970 mbvol
= gain_to_mB(*data
.fl
);
972 hr
= EAX4Source_Set(buf
, EAXSOURCE_ROOM
, &mbvol
, sizeof(mbvol
));
973 if(SUCCEEDED(hr
)) buf
->deferred
.eax1_reverbmix
= *data
.fl
;
976 return DSERR_INVALIDPARAM
;
978 FIXME("Unhandled propid: 0x%08lx\n", propid
);
979 return E_PROP_ID_UNSUPPORTED
;
982 HRESULT
EAX1Buffer_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
986 case DSPROPERTY_EAX10BUFFER_ALL
:
987 case DSPROPERTY_EAX10BUFFER_REVERBMIX
:
988 if(cbPropData
>= sizeof(float))
990 union { void *v
; float *fl
; } data
= { pPropData
};
992 *data
.fl
= buf
->current
.eax1_reverbmix
;
993 *pcbReturned
= sizeof(float);
996 return DSERR_INVALIDPARAM
;
998 FIXME("Unhandled propid: 0x%08lx\n", propid
);
999 return E_PROP_ID_UNSUPPORTED
;