1 /* EAX reverb 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"
29 static void ApplyReverbParams(ALuint effect
, const EAXREVERBPROPERTIES
*props
)
31 /* FIXME: Need to validate property values... Ignore? Clamp? Error? */
32 alEffectf(effect
, AL_EAXREVERB_DENSITY
,
33 clampF(powf(props
->flEnvironmentSize
, 3.0f
) / 16.0f
, 0.0f
, 1.0f
)
35 alEffectf(effect
, AL_EAXREVERB_DIFFUSION
, props
->flEnvironmentDiffusion
);
37 alEffectf(effect
, AL_EAXREVERB_GAIN
, mB_to_gain(props
->lRoom
));
38 alEffectf(effect
, AL_EAXREVERB_GAINHF
, mB_to_gain(props
->lRoomHF
));
39 alEffectf(effect
, AL_EAXREVERB_GAINLF
, mB_to_gain(props
->lRoomLF
));
41 alEffectf(effect
, AL_EAXREVERB_DECAY_TIME
, props
->flDecayTime
);
42 alEffectf(effect
, AL_EAXREVERB_DECAY_HFRATIO
, props
->flDecayHFRatio
);
43 alEffectf(effect
, AL_EAXREVERB_DECAY_LFRATIO
, props
->flDecayLFRatio
);
45 /* NOTE: Imprecision can cause some converted volume levels to land outside
46 * EFX's gain limits (e.g. EAX's +1000mB volume limit gets converted to
47 * 3.162something, while EFX defines the limit as 3.16; close enough for
48 * practical uses, but still technically an error).
50 alEffectf(effect
, AL_EAXREVERB_REFLECTIONS_GAIN
,
51 clampF(mB_to_gain(props
->lReflections
), AL_EAXREVERB_MIN_REFLECTIONS_GAIN
,
52 AL_EAXREVERB_MAX_REFLECTIONS_GAIN
)
54 alEffectf(effect
, AL_EAXREVERB_REFLECTIONS_DELAY
, props
->flReflectionsDelay
);
55 alEffectfv(effect
, AL_EAXREVERB_REFLECTIONS_PAN
, &props
->vReflectionsPan
.x
);
57 alEffectf(effect
, AL_EAXREVERB_LATE_REVERB_GAIN
,
58 clampF(mB_to_gain(props
->lReverb
), AL_EAXREVERB_MIN_LATE_REVERB_GAIN
,
59 AL_EAXREVERB_MAX_LATE_REVERB_GAIN
)
61 alEffectf(effect
, AL_EAXREVERB_LATE_REVERB_DELAY
, props
->flReverbDelay
);
62 alEffectfv(effect
, AL_EAXREVERB_LATE_REVERB_PAN
, &props
->vReverbPan
.x
);
64 alEffectf(effect
, AL_EAXREVERB_ECHO_TIME
, props
->flEchoTime
);
65 alEffectf(effect
, AL_EAXREVERB_ECHO_DEPTH
, props
->flEchoDepth
);
67 alEffectf(effect
, AL_EAXREVERB_MODULATION_TIME
, props
->flModulationTime
);
68 alEffectf(effect
, AL_EAXREVERB_MODULATION_DEPTH
, props
->flModulationDepth
);
70 alEffectf(effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
71 clampF(mB_to_gain(props
->flAirAbsorptionHF
), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF
,
72 AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF
)
75 alEffectf(effect
, AL_EAXREVERB_HFREFERENCE
, props
->flHFReference
);
76 alEffectf(effect
, AL_EAXREVERB_LFREFERENCE
, props
->flLFReference
);
78 alEffectf(effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
, props
->flRoomRolloffFactor
);
80 alEffecti(effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
81 (props
->dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
87 static void RescaleEnvSize(EAXREVERBPROPERTIES
*props
, float newsize
)
89 float scale
= newsize
/ props
->flEnvironmentSize
;
91 props
->flEnvironmentSize
= newsize
;
93 if((props
->dwFlags
&EAX30LISTENERFLAGS_DECAYTIMESCALE
))
95 props
->flDecayTime
*= scale
;
96 props
->flDecayTime
= clampF(props
->flDecayTime
, 0.1f
, 20.0f
);
98 if((props
->dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSSCALE
))
100 props
->lReflections
-= gain_to_mB(scale
);
101 props
->lReflections
= clampI(props
->lReflections
, -10000, 1000);
103 if((props
->dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSDELAYSCALE
))
105 props
->flReflectionsDelay
*= scale
;
106 props
->flReflectionsDelay
= clampF(props
->flReflectionsDelay
, 0.0f
, 0.3f
);
108 if((props
->dwFlags
&EAX30LISTENERFLAGS_REVERBSCALE
))
110 LONG diff
= gain_to_mB(scale
);
111 /* This is scaled by an extra 1/3rd if decay time isn't also scaled, to
112 * account for the (lack of) change on the send's initial decay.
114 if(!(props
->dwFlags
&EAX30LISTENERFLAGS_DECAYTIMESCALE
))
116 props
->lReverb
-= diff
;
117 props
->lReverb
= clampI(props
->lReverb
, -10000, 2000);
119 if((props
->dwFlags
&EAX30LISTENERFLAGS_REVERBDELAYSCALE
))
121 props
->flReverbDelay
*= scale
;
122 props
->flReverbDelay
= clampF(props
->flReverbDelay
, 0.0f
, 0.1f
);
124 if((props
->dwFlags
&EAX30LISTENERFLAGS_ECHOTIMESCALE
))
126 props
->flEchoTime
*= scale
;
127 props
->flEchoTime
= clampF(props
->flEchoTime
, 0.075f
, 0.25f
);
129 if((props
->dwFlags
&EAX30LISTENERFLAGS_MODTIMESCALE
))
131 props
->flModulationTime
*= scale
;
132 props
->flModulationTime
= clampF(props
->flModulationTime
, 0.04f
, 4.0f
);
137 HRESULT
EAXReverb_Set(DSPrimary
*prim
, LONG idx
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
141 case EAXREVERB_NONE
: /* not setting any property, just applying */
144 case EAXREVERB_ALLPARAMETERS
:
145 if(cbPropData
>= sizeof(EAXREVERBPROPERTIES
))
149 const EAXREVERBPROPERTIES
*props
;
150 } data
= { pPropData
};
151 TRACE("Parameters:\n\tEnvironment: %lu\n\tEnvSize: %f\n\tEnvDiffusion: %f\n\t"
152 "Room: %ld\n\tRoom HF: %ld\n\tRoom LF: %ld\n\tDecay Time: %f\n\t"
153 "Decay HF Ratio: %f\n\tDecay LF Ratio: %f\n\tReflections: %ld\n\t"
154 "Reflections Delay: %f\n\tReflections Pan: { %f, %f, %f }\n\tReverb: %ld\n\t"
155 "Reverb Delay: %f\n\tReverb Pan: { %f, %f, %f }\n\tEcho Time: %f\n\t"
156 "Echo Depth: %f\n\tMod Time: %f\n\tMod Depth: %f\n\tAir Absorption: %f\n\t"
157 "HF Reference: %f\n\tLF Reference: %f\n\tRoom Rolloff: %f\n\tFlags: 0x%02lx\n",
158 data
.props
->dwEnvironment
, data
.props
->flEnvironmentSize
,
159 data
.props
->flEnvironmentDiffusion
, data
.props
->lRoom
, data
.props
->lRoomHF
,
160 data
.props
->lRoomLF
, data
.props
->flDecayTime
, data
.props
->flDecayHFRatio
,
161 data
.props
->flDecayLFRatio
, data
.props
->lReflections
,
162 data
.props
->flReflectionsDelay
, data
.props
->vReflectionsPan
.x
,
163 data
.props
->vReflectionsPan
.y
, data
.props
->vReflectionsPan
.z
, data
.props
->lReverb
,
164 data
.props
->flReverbDelay
, data
.props
->vReverbPan
.x
, data
.props
->vReverbPan
.y
,
165 data
.props
->vReverbPan
.z
, data
.props
->flEchoTime
, data
.props
->flEchoDepth
,
166 data
.props
->flModulationTime
, data
.props
->flModulationDepth
,
167 data
.props
->flAirAbsorptionHF
, data
.props
->flHFReference
,
168 data
.props
->flLFReference
, data
.props
->flRoomRolloffFactor
, data
.props
->dwFlags
171 ApplyReverbParams(prim
->effect
[idx
], data
.props
);
172 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
175 return DSERR_INVALIDPARAM
;
177 case EAXREVERB_ENVIRONMENT
:
178 if(cbPropData
>= sizeof(DWORD
))
180 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
181 TRACE("Environment: %lu\n", *data
.dw
);
182 if(*data
.dw
< EAX_ENVIRONMENT_UNDEFINED
)
184 prim
->deferred
.fxslot
[idx
].fx
.reverb
= EnvironmentDefaults
[*data
.dw
];
185 ApplyReverbParams(prim
->effect
[idx
], &EnvironmentDefaults
[*data
.dw
]);
186 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
190 return DSERR_INVALIDPARAM
;
192 case EAXREVERB_ENVIRONMENTSIZE
:
193 if(cbPropData
>= sizeof(float))
195 union { const void *v
; const float *fl
; } data
= { pPropData
};
196 TRACE("Environment Size: %f\n", *data
.fl
);
198 RescaleEnvSize(&prim
->deferred
.fxslot
[idx
].fx
.reverb
, clampF(*data
.fl
, 1.0f
, 100.0f
));
199 ApplyReverbParams(prim
->effect
[idx
], &prim
->deferred
.fxslot
[idx
].fx
.reverb
);
201 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
204 return DSERR_INVALIDPARAM
;
205 case EAXREVERB_ENVIRONMENTDIFFUSION
:
206 if(cbPropData
>= sizeof(float))
208 union { const void *v
; const float *fl
; } data
= { pPropData
};
209 TRACE("Environment Diffusion: %f\n", *data
.fl
);
211 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flEnvironmentDiffusion
= *data
.fl
;
212 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_DIFFUSION
,
213 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flEnvironmentDiffusion
);
216 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
219 return DSERR_INVALIDPARAM
;
222 if(cbPropData
>= sizeof(long))
224 union { const void *v
; const long *l
; } data
= { pPropData
};
225 TRACE("Room: %ld\n", *data
.l
);
227 prim
->deferred
.fxslot
[idx
].fx
.reverb
.lRoom
= *data
.l
;
228 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_GAIN
,
229 mB_to_gain(prim
->deferred
.fxslot
[idx
].fx
.reverb
.lRoom
));
232 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
235 return DSERR_INVALIDPARAM
;
236 case EAXREVERB_ROOMHF
:
237 if(cbPropData
>= sizeof(long))
239 union { const void *v
; const long *l
; } data
= { pPropData
};
240 TRACE("Room HF: %ld\n", *data
.l
);
242 prim
->deferred
.fxslot
[idx
].fx
.reverb
.lRoomHF
= *data
.l
;
243 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_GAINHF
,
244 mB_to_gain(prim
->deferred
.fxslot
[idx
].fx
.reverb
.lRoomHF
));
247 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
250 return DSERR_INVALIDPARAM
;
251 case EAXREVERB_ROOMLF
:
252 if(cbPropData
>= sizeof(long))
254 union { const void *v
; const long *l
; } data
= { pPropData
};
255 TRACE("Room LF: %ld\n", *data
.l
);
257 prim
->deferred
.fxslot
[idx
].fx
.reverb
.lRoomLF
= *data
.l
;
258 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_GAINLF
,
259 mB_to_gain(prim
->deferred
.fxslot
[idx
].fx
.reverb
.lRoomLF
));
262 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
265 return DSERR_INVALIDPARAM
;
267 case EAXREVERB_DECAYTIME
:
268 if(cbPropData
>= sizeof(float))
270 union { const void *v
; const float *fl
; } data
= { pPropData
};
271 TRACE("Decay Time: %f\n", *data
.fl
);
273 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flDecayTime
= *data
.fl
;
274 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_DECAY_TIME
,
275 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flDecayTime
);
278 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
281 return DSERR_INVALIDPARAM
;
282 case EAXREVERB_DECAYHFRATIO
:
283 if(cbPropData
>= sizeof(float))
285 union { const void *v
; const float *fl
; } data
= { pPropData
};
286 TRACE("Decay HF Ratio: %f\n", *data
.fl
);
288 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flDecayHFRatio
= *data
.fl
;
289 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_DECAY_HFRATIO
,
290 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flDecayHFRatio
);
293 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
296 return DSERR_INVALIDPARAM
;
297 case EAXREVERB_DECAYLFRATIO
:
298 if(cbPropData
>= sizeof(float))
300 union { const void *v
; const float *fl
; } data
= { pPropData
};
301 TRACE("Decay LF Ratio: %f\n", *data
.fl
);
303 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flDecayLFRatio
= *data
.fl
;
304 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_DECAY_LFRATIO
,
305 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flDecayLFRatio
);
308 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
311 return DSERR_INVALIDPARAM
;
313 case EAXREVERB_REFLECTIONS
:
314 if(cbPropData
>= sizeof(long))
316 union { const void *v
; const long *l
; } data
= { pPropData
};
317 TRACE("Reflections: %ld\n", *data
.l
);
319 prim
->deferred
.fxslot
[idx
].fx
.reverb
.lReflections
= *data
.l
;
320 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_REFLECTIONS_GAIN
,
321 mB_to_gain(prim
->deferred
.fxslot
[idx
].fx
.reverb
.lReflections
));
324 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
327 return DSERR_INVALIDPARAM
;
328 case EAXREVERB_REFLECTIONSDELAY
:
329 if(cbPropData
>= sizeof(float))
331 union { const void *v
; const float *fl
; } data
= { pPropData
};
332 TRACE("Reflections Delay: %f\n", *data
.fl
);
334 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flReflectionsDelay
= *data
.fl
;
335 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_REFLECTIONS_DELAY
,
336 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flReflectionsDelay
);
339 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
342 return DSERR_INVALIDPARAM
;
343 case EAXREVERB_REFLECTIONSPAN
:
344 if(cbPropData
>= sizeof(EAXVECTOR
))
346 union { const void *v
; const EAXVECTOR
*vec
; } data
= { pPropData
};
347 TRACE("Reflections Pan: { %f, %f, %f }\n", data
.vec
->x
, data
.vec
->y
, data
.vec
->z
);
349 prim
->deferred
.fxslot
[idx
].fx
.reverb
.vReflectionsPan
= *data
.vec
;
350 alEffectfv(prim
->effect
[idx
], AL_EAXREVERB_REFLECTIONS_PAN
,
351 &prim
->deferred
.fxslot
[idx
].fx
.reverb
.vReflectionsPan
.x
);
354 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
357 return DSERR_INVALIDPARAM
;
359 case EAXREVERB_REVERB
:
360 if(cbPropData
>= sizeof(long))
362 union { const void *v
; const long *l
; } data
= { pPropData
};
363 TRACE("Reverb: %ld\n", *data
.l
);
365 prim
->deferred
.fxslot
[idx
].fx
.reverb
.lReverb
= *data
.l
;
366 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_LATE_REVERB_GAIN
,
367 mB_to_gain(prim
->deferred
.fxslot
[idx
].fx
.reverb
.lReverb
));
370 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
373 return DSERR_INVALIDPARAM
;
374 case EAXREVERB_REVERBDELAY
:
375 if(cbPropData
>= sizeof(float))
377 union { const void *v
; const float *fl
; } data
= { pPropData
};
378 TRACE("Reverb Delay: %f\n", *data
.fl
);
380 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flReverbDelay
= *data
.fl
;
381 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_LATE_REVERB_DELAY
,
382 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flReverbDelay
);
385 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
388 return DSERR_INVALIDPARAM
;
389 case EAXREVERB_REVERBPAN
:
390 if(cbPropData
>= sizeof(EAXVECTOR
))
392 union { const void *v
; const EAXVECTOR
*vec
; } data
= { pPropData
};
393 TRACE("Reverb Pan: { %f, %f, %f }\n", data
.vec
->x
, data
.vec
->y
, data
.vec
->z
);
395 prim
->deferred
.fxslot
[idx
].fx
.reverb
.vReverbPan
= *data
.vec
;
396 alEffectfv(prim
->effect
[idx
], AL_EAXREVERB_LATE_REVERB_PAN
,
397 &prim
->deferred
.fxslot
[idx
].fx
.reverb
.vReverbPan
.x
);
400 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
403 return DSERR_INVALIDPARAM
;
405 case EAXREVERB_ECHOTIME
:
406 if(cbPropData
>= sizeof(float))
408 union { const void *v
; const float *fl
; } data
= { pPropData
};
409 TRACE("Echo Time: %f\n", *data
.fl
);
411 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flEchoTime
= *data
.fl
;
412 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_ECHO_TIME
,
413 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flEchoTime
);
416 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
419 return DSERR_INVALIDPARAM
;
420 case EAXREVERB_ECHODEPTH
:
421 if(cbPropData
>= sizeof(float))
423 union { const void *v
; const float *fl
; } data
= { pPropData
};
424 TRACE("Echo Depth: %f\n", *data
.fl
);
426 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flEchoDepth
= *data
.fl
;
427 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_ECHO_DEPTH
,
428 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flEchoDepth
);
431 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
434 return DSERR_INVALIDPARAM
;
436 case EAXREVERB_MODULATIONTIME
:
437 if(cbPropData
>= sizeof(float))
439 union { const void *v
; const float *fl
; } data
= { pPropData
};
440 TRACE("Modulation Time: %f\n", *data
.fl
);
442 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flModulationTime
= *data
.fl
;
443 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_MODULATION_TIME
,
444 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flModulationTime
);
447 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
450 return DSERR_INVALIDPARAM
;
451 case EAXREVERB_MODULATIONDEPTH
:
452 if(cbPropData
>= sizeof(float))
454 union { const void *v
; const float *fl
; } data
= { pPropData
};
455 TRACE("Modulation Depth: %f\n", *data
.fl
);
457 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flModulationDepth
= *data
.fl
;
458 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_MODULATION_DEPTH
,
459 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flModulationDepth
);
462 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
465 return DSERR_INVALIDPARAM
;
467 case EAXREVERB_AIRABSORPTIONHF
:
468 if(cbPropData
>= sizeof(float))
470 union { const void *v
; const float *fl
; } data
= { pPropData
};
471 TRACE("Air Absorption HF: %f\n", *data
.fl
);
473 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flAirAbsorptionHF
= *data
.fl
;
474 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
475 mB_to_gain(prim
->deferred
.fxslot
[idx
].fx
.reverb
.flAirAbsorptionHF
));
478 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
481 return DSERR_INVALIDPARAM
;
483 case EAXREVERB_HFREFERENCE
:
484 if(cbPropData
>= sizeof(float))
486 union { const void *v
; const float *fl
; } data
= { pPropData
};
487 TRACE("HF Reference: %f\n", *data
.fl
);
489 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flHFReference
= *data
.fl
;
490 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_HFREFERENCE
,
491 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flHFReference
);
494 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
497 return DSERR_INVALIDPARAM
;
498 case EAXREVERB_LFREFERENCE
:
499 if(cbPropData
>= sizeof(float))
501 union { const void *v
; const float *fl
; } data
= { pPropData
};
502 TRACE("LF Reference: %f\n", *data
.fl
);
504 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flLFReference
= *data
.fl
;
505 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_LFREFERENCE
,
506 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flLFReference
);
509 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
512 return DSERR_INVALIDPARAM
;
514 case EAXREVERB_ROOMROLLOFFFACTOR
:
515 if(cbPropData
>= sizeof(float))
517 union { const void *v
; const float *fl
; } data
= { pPropData
};
518 TRACE("Room Rolloff Factor: %f\n", *data
.fl
);
520 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flRoomRolloffFactor
= *data
.fl
;
521 alEffectf(prim
->effect
[idx
], AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
,
522 prim
->deferred
.fxslot
[idx
].fx
.reverb
.flRoomRolloffFactor
);
525 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
528 return DSERR_INVALIDPARAM
;
530 case EAXREVERB_FLAGS
:
531 if(cbPropData
>= sizeof(DWORD
))
533 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
534 TRACE("Flags: %lu\n", *data
.dw
);
536 prim
->deferred
.fxslot
[idx
].fx
.reverb
.dwFlags
= *data
.dw
;
537 alEffecti(prim
->effect
[idx
], AL_EAXREVERB_DECAY_HFLIMIT
,
538 (prim
->deferred
.fxslot
[idx
].fx
.reverb
.dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
543 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
546 return DSERR_INVALIDPARAM
;
548 FIXME("Unhandled propid: 0x%08lx\n", propid
);
549 return E_PROP_ID_UNSUPPORTED
;
552 #define GET_PROP(src, T) do { \
553 if(cbPropData >= sizeof(T)) \
555 union { void *v; T *props; } data = { pPropData }; \
557 *pcbReturned = sizeof(T); \
560 return DSERR_INVALIDPARAM; \
563 HRESULT
EAXReverb_Get(DSPrimary
*prim
, DWORD idx
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
571 case EAXREVERB_ALLPARAMETERS
:
572 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
, EAXREVERBPROPERTIES
);
574 case EAXREVERB_ENVIRONMENT
:
575 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.dwEnvironment
, DWORD
);
577 case EAXREVERB_ENVIRONMENTSIZE
:
578 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flEnvironmentSize
, float);
579 case EAXREVERB_ENVIRONMENTDIFFUSION
:
580 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flEnvironmentDiffusion
, float);
583 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.lRoom
, long);
584 case EAXREVERB_ROOMHF
:
585 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.lRoomHF
, long);
586 case EAXREVERB_ROOMLF
:
587 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.lRoomLF
, long);
589 case EAXREVERB_DECAYTIME
:
590 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flDecayTime
, float);
591 case EAXREVERB_DECAYHFRATIO
:
592 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flDecayHFRatio
, float);
593 case EAXREVERB_DECAYLFRATIO
:
594 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flDecayLFRatio
, float);
596 case EAXREVERB_REFLECTIONS
:
597 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.lReflections
, long);
598 case EAXREVERB_REFLECTIONSDELAY
:
599 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flReflectionsDelay
, float);
600 case EAXREVERB_REFLECTIONSPAN
:
601 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.vReflectionsPan
, EAXVECTOR
);
603 case EAXREVERB_REVERB
:
604 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.lReverb
, long);
605 case EAXREVERB_REVERBDELAY
:
606 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flReverbDelay
, float);
607 case EAXREVERB_REVERBPAN
:
608 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.vReverbPan
, EAXVECTOR
);
610 case EAXREVERB_ECHOTIME
:
611 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flEchoTime
, float);
612 case EAXREVERB_ECHODEPTH
:
613 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flEchoDepth
, float);
615 case EAXREVERB_MODULATIONTIME
:
616 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flModulationTime
, float);
617 case EAXREVERB_MODULATIONDEPTH
:
618 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flModulationDepth
, float);
620 case EAXREVERB_AIRABSORPTIONHF
:
621 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flAirAbsorptionHF
, float);
623 case EAXREVERB_HFREFERENCE
:
624 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flHFReference
, float);
625 case EAXREVERB_LFREFERENCE
:
626 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flLFReference
, float);
628 case EAXREVERB_ROOMROLLOFFFACTOR
:
629 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.flRoomRolloffFactor
, float);
631 case EAXREVERB_FLAGS
:
632 GET_PROP(prim
->current
.fxslot
[idx
].fx
.reverb
.dwFlags
, DWORD
);
634 FIXME("Unhandled propid: 0x%08lx\n", propid
);
635 return E_PROP_ID_UNSUPPORTED
;