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"
29 static void ApplyReverbParams(DS8Primary
*prim
, const EAX30LISTENERPROPERTIES
*props
)
31 /* FIXME: Need to validate property values... Ignore? Clamp? Error? */
32 prim
->deferred
.eax
= *props
;
33 alEffectf(prim
->effect
, AL_EAXREVERB_DENSITY
,
34 clampF(powf(props
->flEnvironmentSize
, 3.0f
) / 16.0f
, 0.0f
, 1.0f
)
36 alEffectf(prim
->effect
, AL_EAXREVERB_DIFFUSION
, props
->flEnvironmentDiffusion
);
38 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
, mB_to_gain(props
->lRoom
));
39 alEffectf(prim
->effect
, AL_EAXREVERB_GAINHF
, mB_to_gain(props
->lRoomHF
));
40 alEffectf(prim
->effect
, AL_EAXREVERB_GAINLF
, mB_to_gain(props
->lRoomLF
));
42 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
, props
->flDecayTime
);
43 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_HFRATIO
, props
->flDecayHFRatio
);
44 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_LFRATIO
, props
->flDecayLFRatio
);
46 /* NOTE: Imprecision can cause some converted volume levels to land outside
47 * EFX's gain limits (e.g. EAX's +1000mB volume limit gets converted to
48 * 3.162something, while EFX defines the limit as 3.16; close enough for
49 * practical uses, but still technically an error).
51 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_GAIN
,
52 clampF(mB_to_gain(props
->lReflections
), AL_EAXREVERB_MIN_REFLECTIONS_GAIN
,
53 AL_EAXREVERB_MAX_REFLECTIONS_GAIN
)
55 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_DELAY
, props
->flReflectionsDelay
);
56 alEffectfv(prim
->effect
, AL_EAXREVERB_REFLECTIONS_PAN
, &props
->vReflectionsPan
.x
);
58 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_GAIN
,
59 clampF(mB_to_gain(props
->lReverb
), AL_EAXREVERB_MIN_LATE_REVERB_GAIN
,
60 AL_EAXREVERB_MAX_LATE_REVERB_GAIN
)
62 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_DELAY
, props
->flReverbDelay
);
63 alEffectfv(prim
->effect
, AL_EAXREVERB_LATE_REVERB_PAN
, &props
->vReverbPan
.x
);
65 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_TIME
, props
->flEchoTime
);
66 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_DEPTH
, props
->flEchoDepth
);
68 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_TIME
, props
->flModulationTime
);
69 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_DEPTH
, props
->flModulationDepth
);
71 alEffectf(prim
->effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
72 clampF(mB_to_gain(props
->flAirAbsorptionHF
), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF
,
73 AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF
)
76 alEffectf(prim
->effect
, AL_EAXREVERB_HFREFERENCE
, props
->flHFReference
);
77 alEffectf(prim
->effect
, AL_EAXREVERB_LFREFERENCE
, props
->flLFReference
);
79 alEffectf(prim
->effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
, props
->flRoomRolloffFactor
);
81 alEffecti(prim
->effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
82 (props
->dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
87 prim
->dirty
.bit
.effect
= 1;
90 static inline float minF(float a
, float b
)
91 { return (a
<= b
) ? a
: b
; }
92 static inline float maxF(float a
, float b
)
93 { return (a
>= b
) ? a
: b
; }
95 #define APPLY_DRY_PARAMS 1
96 #define APPLY_WET_PARAMS 2
97 static void ApplyFilterParams(DS8Buffer
*buf
, const EAX30BUFFERPROPERTIES
*props
, int apply
)
99 /* The LFRatio properties determine how much the given level applies to low
100 * frequencies as well as high frequencies. Technically, given that the
101 * obstruction/occlusion/exclusion levels are the absolute level applied to
102 * high frequencies (relative to full-scale, according to the EAX 2.0 spec)
103 * while the HF filter gains are relative to the low, the HF gains should
104 * increase as LFRatio increases.
106 * However it seems Creative was either wrong when writing out the spec,
107 * or implemented it incorrectly, as the HF filter still applies in full
108 * regardless of the LFRatio. So to replicate the hardware behavior, we do
112 if((apply
&APPLY_DRY_PARAMS
))
114 float mb
= props
->lDirect
+ props
->lObstruction
*props
->flObstructionLFRatio
;
115 float mbhf
= props
->lDirectHF
+ props
->lObstruction
;
116 /* The interaction of ratios is pretty wierd. The typical combination
117 * of the two act as a minimal baseline, while the sum minus one is
118 * used when larger. This creates a more linear change with the
119 * individual ratios as DirectRatio goes beyond 1, but eases down as
120 * the two ratios go toward 0.
122 mb
+= maxF(props
->flOcclusionLFRatio
+props
->flOcclusionDirectRatio
-1.0f
,
123 props
->flOcclusionLFRatio
*props
->flOcclusionDirectRatio
) * props
->lOcclusion
;
124 mbhf
+= props
->lOcclusion
* props
->flOcclusionDirectRatio
;
126 alFilterf(buf
->filter
[0], AL_LOWPASS_GAIN
, minF(mB_to_gain(mb
), 1.0f
));
127 alFilterf(buf
->filter
[0], AL_LOWPASS_GAINHF
, mB_to_gain(mbhf
));
129 if((apply
&APPLY_WET_PARAMS
))
131 float mb
= props
->lRoom
+ props
->lExclusion
*props
->flExclusionLFRatio
;
132 float mbhf
= props
->lRoomHF
+ props
->lExclusion
;
133 mb
+= maxF(props
->flOcclusionLFRatio
+props
->flOcclusionRoomRatio
-1.0f
,
134 props
->flOcclusionLFRatio
*props
->flOcclusionRoomRatio
) * props
->lOcclusion
;
135 mbhf
+= props
->lOcclusion
* props
->flOcclusionRoomRatio
;
137 alFilterf(buf
->filter
[1], AL_LOWPASS_GAIN
, minF(mB_to_gain(mb
), 1.0f
));
138 alFilterf(buf
->filter
[1], AL_LOWPASS_GAINHF
, mB_to_gain(mbhf
));
144 static void RescaleEnvSize(EAX30LISTENERPROPERTIES
*props
, float newsize
)
146 float scale
= newsize
/ props
->flEnvironmentSize
;
148 props
->flEnvironmentSize
= newsize
;
150 if((props
->dwFlags
&EAX30LISTENERFLAGS_DECAYTIMESCALE
))
152 props
->flDecayTime
*= scale
;
153 props
->flDecayTime
= clampF(props
->flDecayTime
, 0.1f
, 20.0f
);
155 if((props
->dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSSCALE
))
157 props
->lReflections
-= gain_to_mB(scale
);
158 props
->lReflections
= clampI(props
->lReflections
, -10000, 1000);
160 if((props
->dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSDELAYSCALE
))
162 props
->flReflectionsDelay
*= scale
;
163 props
->flReflectionsDelay
= clampF(props
->flReflectionsDelay
, 0.0f
, 0.3f
);
165 if((props
->dwFlags
&EAX30LISTENERFLAGS_REVERBSCALE
))
167 LONG diff
= gain_to_mB(scale
);
168 /* This is scaled by an extra 1/3rd if decay time isn't also scaled, to
169 * account for the (lack of) change on the send's initial decay.
171 if(!(props
->dwFlags
&EAX30LISTENERFLAGS_DECAYTIMESCALE
))
173 props
->lReverb
-= diff
;
174 props
->lReverb
= clampI(props
->lReverb
, -10000, 2000);
176 if((props
->dwFlags
&EAX30LISTENERFLAGS_REVERBDELAYSCALE
))
178 props
->flReverbDelay
*= scale
;
179 props
->flReverbDelay
= clampF(props
->flReverbDelay
, 0.0f
, 0.1f
);
181 if((props
->dwFlags
&EAX30LISTENERFLAGS_ECHOTIMESCALE
))
183 props
->flEchoTime
*= scale
;
184 props
->flEchoTime
= clampF(props
->flEchoTime
, 0.075f
, 0.25f
);
186 if((props
->dwFlags
&EAX30LISTENERFLAGS_MODTIMESCALE
))
188 props
->flModulationTime
*= scale
;
189 props
->flModulationTime
= clampF(props
->flModulationTime
, 0.04f
, 4.0f
);
198 static EAXOBSTRUCTIONPROPERTIES
EAX3BufferObstruction(const EAX30BUFFERPROPERTIES
*props
)
200 EAXOBSTRUCTIONPROPERTIES ret
;
201 ret
.lObstruction
= props
->lObstruction
;
202 ret
.flObstructionLFRatio
= props
->flObstructionLFRatio
;
206 static EAXOCCLUSIONPROPERTIES
EAX3BufferOcclusion(const EAX30BUFFERPROPERTIES
*props
)
208 EAXOCCLUSIONPROPERTIES ret
;
209 ret
.lOcclusion
= props
->lOcclusion
;
210 ret
.flOcclusionLFRatio
= props
->flOcclusionLFRatio
;
211 ret
.flOcclusionRoomRatio
= props
->flOcclusionRoomRatio
;
212 ret
.flOcclusionDirectRatio
= props
->flOcclusionDirectRatio
;
216 static EAXEXCLUSIONPROPERTIES
EAX3BufferExclusion(const EAX30BUFFERPROPERTIES
*props
)
218 EAXEXCLUSIONPROPERTIES ret
;
219 ret
.lExclusion
= props
->lExclusion
;
220 ret
.flExclusionLFRatio
= props
->flExclusionLFRatio
;
224 HRESULT
EAX3_Query(DS8Primary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
226 if(prim
->effect
== 0)
227 return E_PROP_ID_UNSUPPORTED
;
231 case DSPROPERTY_EAX30LISTENER_NONE
:
232 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
233 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
234 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
235 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
236 case DSPROPERTY_EAX30LISTENER_ROOM
:
237 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
238 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
239 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
240 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
241 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
242 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
243 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
244 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
245 case DSPROPERTY_EAX30LISTENER_REVERB
:
246 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
247 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
248 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
249 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
250 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
251 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
252 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
253 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
254 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
255 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
256 case DSPROPERTY_EAX30LISTENER_FLAGS
:
257 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
261 FIXME("Unhandled propid: 0x%08lx\n", propid
);
263 return E_PROP_ID_UNSUPPORTED
;
266 HRESULT
EAX3_Set(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
270 if(prim
->effect
== 0)
271 return E_PROP_ID_UNSUPPORTED
;
273 hr
= DSERR_INVALIDPARAM
;
276 case DSPROPERTY_EAX30LISTENER_NONE
: /* not setting any property, just applying */
280 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
281 if(cbPropData
>= sizeof(EAX30LISTENERPROPERTIES
))
285 const EAX30LISTENERPROPERTIES
*props
;
286 } data
= { pPropData
};
287 TRACE("Parameters:\n\tEnvironment: %lu\n\tEnvSize: %f\n\tEnvDiffusion: %f\n\t"
288 "Room: %ld\n\tRoom HF: %ld\n\tRoom LF: %ld\n\tDecay Time: %f\n\t"
289 "Decay HF Ratio: %f\n\tDecay LF Ratio: %f\n\tReflections: %ld\n\t"
290 "Reflections Delay: %f\n\tReflections Pan: { %f, %f, %f }\n\tReverb: %ld\n\t"
291 "Reverb Delay: %f\n\tReverb Pan: { %f, %f, %f }\n\tEcho Time: %f\n\t"
292 "Echo Depth: %f\n\tMod Time: %f\n\tMod Depth: %f\n\tAir Absorption: %f\n\t"
293 "HF Reference: %f\n\tLF Reference: %f\n\tRoom Rolloff: %f\n\tFlags: 0x%02lx\n",
294 data
.props
->dwEnvironment
, data
.props
->flEnvironmentSize
,
295 data
.props
->flEnvironmentDiffusion
, data
.props
->lRoom
, data
.props
->lRoomHF
,
296 data
.props
->lRoomLF
, data
.props
->flDecayTime
, data
.props
->flDecayHFRatio
,
297 data
.props
->flDecayLFRatio
, data
.props
->lReflections
,
298 data
.props
->flReflectionsDelay
, data
.props
->vReflectionsPan
.x
,
299 data
.props
->vReflectionsPan
.y
, data
.props
->vReflectionsPan
.z
, data
.props
->lReverb
,
300 data
.props
->flReverbDelay
, data
.props
->vReverbPan
.x
, data
.props
->vReverbPan
.y
,
301 data
.props
->vReverbPan
.z
, data
.props
->flEchoTime
, data
.props
->flEchoDepth
,
302 data
.props
->flModulationTime
, data
.props
->flModulationDepth
,
303 data
.props
->flAirAbsorptionHF
, data
.props
->flHFReference
,
304 data
.props
->flLFReference
, data
.props
->flRoomRolloffFactor
, data
.props
->dwFlags
307 ApplyReverbParams(prim
, data
.props
);
312 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
313 if(cbPropData
>= sizeof(DWORD
))
315 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
316 TRACE("Environment: %lu\n", *data
.dw
);
317 if(*data
.dw
< EAX_ENVIRONMENT_UNDEFINED
)
319 ApplyReverbParams(prim
, &EnvironmentDefaults
[*data
.dw
]);
325 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
326 if(cbPropData
>= sizeof(float))
328 union { const void *v
; const float *fl
; } data
= { pPropData
};
329 TRACE("Environment Size: %f\n", *data
.fl
);
331 RescaleEnvSize(&prim
->deferred
.eax
, clampF(*data
.fl
, 1.0f
, 100.0f
));
333 ApplyReverbParams(prim
, &prim
->deferred
.eax
);
337 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
338 if(cbPropData
>= sizeof(float))
340 union { const void *v
; const float *fl
; } data
= { pPropData
};
341 TRACE("Environment Diffusion: %f\n", *data
.fl
);
343 prim
->deferred
.eax
.flEnvironmentDiffusion
= *data
.fl
;
344 alEffectf(prim
->effect
, AL_EAXREVERB_DIFFUSION
,
345 prim
->deferred
.eax
.flEnvironmentDiffusion
);
348 prim
->dirty
.bit
.effect
= 1;
353 case DSPROPERTY_EAX30LISTENER_ROOM
:
354 if(cbPropData
>= sizeof(long))
356 union { const void *v
; const long *l
; } data
= { pPropData
};
357 TRACE("Room: %ld\n", *data
.l
);
359 prim
->deferred
.eax
.lRoom
= *data
.l
;
360 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
,
361 mB_to_gain(prim
->deferred
.eax
.lRoom
));
364 prim
->dirty
.bit
.effect
= 1;
368 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
369 if(cbPropData
>= sizeof(long))
371 union { const void *v
; const long *l
; } data
= { pPropData
};
372 TRACE("Room HF: %ld\n", *data
.l
);
374 prim
->deferred
.eax
.lRoomHF
= *data
.l
;
375 alEffectf(prim
->effect
, AL_EAXREVERB_GAINHF
,
376 mB_to_gain(prim
->deferred
.eax
.lRoomHF
));
379 prim
->dirty
.bit
.effect
= 1;
383 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
384 if(cbPropData
>= sizeof(long))
386 union { const void *v
; const long *l
; } data
= { pPropData
};
387 TRACE("Room LF: %ld\n", *data
.l
);
389 prim
->deferred
.eax
.lRoomLF
= *data
.l
;
390 alEffectf(prim
->effect
, AL_EAXREVERB_GAINLF
,
391 mB_to_gain(prim
->deferred
.eax
.lRoomLF
));
394 prim
->dirty
.bit
.effect
= 1;
399 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
400 if(cbPropData
>= sizeof(float))
402 union { const void *v
; const float *fl
; } data
= { pPropData
};
403 TRACE("Decay Time: %f\n", *data
.fl
);
405 prim
->deferred
.eax
.flDecayTime
= *data
.fl
;
406 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
,
407 prim
->deferred
.eax
.flDecayTime
);
410 prim
->dirty
.bit
.effect
= 1;
414 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
415 if(cbPropData
>= sizeof(float))
417 union { const void *v
; const float *fl
; } data
= { pPropData
};
418 TRACE("Decay HF Ratio: %f\n", *data
.fl
);
420 prim
->deferred
.eax
.flDecayHFRatio
= *data
.fl
;
421 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_HFRATIO
,
422 prim
->deferred
.eax
.flDecayHFRatio
);
425 prim
->dirty
.bit
.effect
= 1;
429 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
430 if(cbPropData
>= sizeof(float))
432 union { const void *v
; const float *fl
; } data
= { pPropData
};
433 TRACE("Decay LF Ratio: %f\n", *data
.fl
);
435 prim
->deferred
.eax
.flDecayLFRatio
= *data
.fl
;
436 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_LFRATIO
,
437 prim
->deferred
.eax
.flDecayLFRatio
);
440 prim
->dirty
.bit
.effect
= 1;
445 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
446 if(cbPropData
>= sizeof(long))
448 union { const void *v
; const long *l
; } data
= { pPropData
};
449 TRACE("Reflections: %ld\n", *data
.l
);
451 prim
->deferred
.eax
.lReflections
= *data
.l
;
452 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_GAIN
,
453 mB_to_gain(prim
->deferred
.eax
.lReflections
));
456 prim
->dirty
.bit
.effect
= 1;
460 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
461 if(cbPropData
>= sizeof(float))
463 union { const void *v
; const float *fl
; } data
= { pPropData
};
464 TRACE("Reflections Delay: %f\n", *data
.fl
);
466 prim
->deferred
.eax
.flReflectionsDelay
= *data
.fl
;
467 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_DELAY
,
468 prim
->deferred
.eax
.flReflectionsDelay
);
471 prim
->dirty
.bit
.effect
= 1;
475 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
476 if(cbPropData
>= sizeof(EAXVECTOR
))
478 union { const void *v
; const EAXVECTOR
*vec
; } data
= { pPropData
};
479 TRACE("Reflections Pan: { %f, %f, %f }\n", data
.vec
->x
, data
.vec
->y
, data
.vec
->z
);
481 prim
->deferred
.eax
.vReflectionsPan
= *data
.vec
;
482 alEffectfv(prim
->effect
, AL_EAXREVERB_REFLECTIONS_PAN
,
483 &prim
->deferred
.eax
.vReflectionsPan
.x
);
486 prim
->dirty
.bit
.effect
= 1;
491 case DSPROPERTY_EAX30LISTENER_REVERB
:
492 if(cbPropData
>= sizeof(long))
494 union { const void *v
; const long *l
; } data
= { pPropData
};
495 TRACE("Reverb: %ld\n", *data
.l
);
497 prim
->deferred
.eax
.lReverb
= *data
.l
;
498 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_GAIN
,
499 mB_to_gain(prim
->deferred
.eax
.lReverb
));
502 prim
->dirty
.bit
.effect
= 1;
506 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
507 if(cbPropData
>= sizeof(float))
509 union { const void *v
; const float *fl
; } data
= { pPropData
};
510 TRACE("Reverb Delay: %f\n", *data
.fl
);
512 prim
->deferred
.eax
.flReverbDelay
= *data
.fl
;
513 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_DELAY
,
514 prim
->deferred
.eax
.flReverbDelay
);
517 prim
->dirty
.bit
.effect
= 1;
521 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
522 if(cbPropData
>= sizeof(EAXVECTOR
))
524 union { const void *v
; const EAXVECTOR
*vec
; } data
= { pPropData
};
525 TRACE("Reverb Pan: { %f, %f, %f }\n", data
.vec
->x
, data
.vec
->y
, data
.vec
->z
);
527 prim
->deferred
.eax
.vReverbPan
= *data
.vec
;
528 alEffectfv(prim
->effect
, AL_EAXREVERB_LATE_REVERB_PAN
,
529 &prim
->deferred
.eax
.vReverbPan
.x
);
532 prim
->dirty
.bit
.effect
= 1;
537 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
538 if(cbPropData
>= sizeof(float))
540 union { const void *v
; const float *fl
; } data
= { pPropData
};
541 TRACE("Echo Time: %f\n", *data
.fl
);
543 prim
->deferred
.eax
.flEchoTime
= *data
.fl
;
544 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_TIME
,
545 prim
->deferred
.eax
.flEchoTime
);
548 prim
->dirty
.bit
.effect
= 1;
552 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
553 if(cbPropData
>= sizeof(float))
555 union { const void *v
; const float *fl
; } data
= { pPropData
};
556 TRACE("Echo Depth: %f\n", *data
.fl
);
558 prim
->deferred
.eax
.flEchoDepth
= *data
.fl
;
559 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_DEPTH
,
560 prim
->deferred
.eax
.flEchoDepth
);
563 prim
->dirty
.bit
.effect
= 1;
568 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
569 if(cbPropData
>= sizeof(float))
571 union { const void *v
; const float *fl
; } data
= { pPropData
};
572 TRACE("Modulation Time: %f\n", *data
.fl
);
574 prim
->deferred
.eax
.flModulationTime
= *data
.fl
;
575 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_TIME
,
576 prim
->deferred
.eax
.flModulationTime
);
579 prim
->dirty
.bit
.effect
= 1;
583 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
584 if(cbPropData
>= sizeof(float))
586 union { const void *v
; const float *fl
; } data
= { pPropData
};
587 TRACE("Modulation Depth: %f\n", *data
.fl
);
589 prim
->deferred
.eax
.flModulationDepth
= *data
.fl
;
590 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_DEPTH
,
591 prim
->deferred
.eax
.flModulationDepth
);
594 prim
->dirty
.bit
.effect
= 1;
599 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
600 if(cbPropData
>= sizeof(float))
602 union { const void *v
; const float *fl
; } data
= { pPropData
};
603 TRACE("Air Absorption HF: %f\n", *data
.fl
);
605 prim
->deferred
.eax
.flAirAbsorptionHF
= *data
.fl
;
606 alEffectf(prim
->effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
607 mB_to_gain(prim
->deferred
.eax
.flAirAbsorptionHF
));
610 prim
->dirty
.bit
.effect
= 1;
615 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
616 if(cbPropData
>= sizeof(float))
618 union { const void *v
; const float *fl
; } data
= { pPropData
};
619 TRACE("HF Reference: %f\n", *data
.fl
);
621 prim
->deferred
.eax
.flHFReference
= *data
.fl
;
622 alEffectf(prim
->effect
, AL_EAXREVERB_HFREFERENCE
,
623 prim
->deferred
.eax
.flHFReference
);
626 prim
->dirty
.bit
.effect
= 1;
630 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
631 if(cbPropData
>= sizeof(float))
633 union { const void *v
; const float *fl
; } data
= { pPropData
};
634 TRACE("LF Reference: %f\n", *data
.fl
);
636 prim
->deferred
.eax
.flLFReference
= *data
.fl
;
637 alEffectf(prim
->effect
, AL_EAXREVERB_LFREFERENCE
,
638 prim
->deferred
.eax
.flLFReference
);
641 prim
->dirty
.bit
.effect
= 1;
646 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
647 if(cbPropData
>= sizeof(float))
649 union { const void *v
; const float *fl
; } data
= { pPropData
};
650 TRACE("Room Rolloff Factor: %f\n", *data
.fl
);
652 prim
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
653 alEffectf(prim
->effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
,
654 prim
->deferred
.eax
.flRoomRolloffFactor
);
657 prim
->dirty
.bit
.effect
= 1;
662 case DSPROPERTY_EAX30LISTENER_FLAGS
:
663 if(cbPropData
>= sizeof(DWORD
))
665 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
666 TRACE("Flags: %lu\n", *data
.dw
);
668 prim
->deferred
.eax
.dwFlags
= *data
.dw
;
669 alEffecti(prim
->effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
670 (prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
674 prim
->dirty
.bit
.effect
= 1;
680 hr
= E_PROP_ID_UNSUPPORTED
;
681 FIXME("Unhandled propid: 0x%08lx\n", propid
);
688 HRESULT
EAX3_Get(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
692 if(prim
->effect
== 0)
693 return E_PROP_ID_UNSUPPORTED
;
695 #define GET_PROP(src, T) do { \
696 if(cbPropData >= sizeof(T)) \
698 union { void *v; T *props; } data = { pPropData }; \
700 *pcbReturned = sizeof(T); \
704 hr
= DSERR_INVALIDPARAM
;
707 case DSPROPERTY_EAX30LISTENER_NONE
:
712 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
713 GET_PROP(prim
->deferred
.eax
, EAX30LISTENERPROPERTIES
);
716 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
717 GET_PROP(prim
->deferred
.eax
.dwEnvironment
, DWORD
);
720 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
721 GET_PROP(prim
->deferred
.eax
.flEnvironmentSize
, float);
723 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
724 GET_PROP(prim
->deferred
.eax
.flEnvironmentDiffusion
, float);
727 case DSPROPERTY_EAX30LISTENER_ROOM
:
728 GET_PROP(prim
->deferred
.eax
.lRoom
, long);
730 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
731 GET_PROP(prim
->deferred
.eax
.lRoomHF
, long);
733 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
734 GET_PROP(prim
->deferred
.eax
.lRoomLF
, long);
737 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
738 GET_PROP(prim
->deferred
.eax
.flDecayTime
, float);
740 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
741 GET_PROP(prim
->deferred
.eax
.flDecayHFRatio
, float);
743 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
744 GET_PROP(prim
->deferred
.eax
.flDecayLFRatio
, float);
747 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
748 GET_PROP(prim
->deferred
.eax
.lReflections
, long);
750 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
751 GET_PROP(prim
->deferred
.eax
.flReflectionsDelay
, float);
753 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
754 GET_PROP(prim
->deferred
.eax
.vReflectionsPan
, EAXVECTOR
);
757 case DSPROPERTY_EAX30LISTENER_REVERB
:
758 GET_PROP(prim
->deferred
.eax
.lReverb
, long);
760 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
761 GET_PROP(prim
->deferred
.eax
.flReverbDelay
, float);
763 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
764 GET_PROP(prim
->deferred
.eax
.vReverbPan
, EAXVECTOR
);
767 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
768 GET_PROP(prim
->deferred
.eax
.flEchoTime
, float);
770 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
771 GET_PROP(prim
->deferred
.eax
.flEchoDepth
, float);
774 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
775 GET_PROP(prim
->deferred
.eax
.flModulationTime
, float);
777 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
778 GET_PROP(prim
->deferred
.eax
.flModulationDepth
, float);
781 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
782 GET_PROP(prim
->deferred
.eax
.flAirAbsorptionHF
, float);
785 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
786 GET_PROP(prim
->deferred
.eax
.flHFReference
, float);
788 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
789 GET_PROP(prim
->deferred
.eax
.flLFReference
, float);
792 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
793 GET_PROP(prim
->deferred
.eax
.flRoomRolloffFactor
, float);
796 case DSPROPERTY_EAX30LISTENER_FLAGS
:
797 GET_PROP(prim
->deferred
.eax
.dwFlags
, DWORD
);
801 hr
= E_PROP_ID_UNSUPPORTED
;
802 FIXME("Unhandled propid: 0x%08lx\n", propid
);
811 HRESULT
EAX3Buffer_Query(DS8Buffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
813 if(buf
->filter
[0] == 0)
814 return E_PROP_ID_UNSUPPORTED
;
818 case DSPROPERTY_EAX30BUFFER_NONE
:
819 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
820 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS
:
821 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS
:
822 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS
:
823 case DSPROPERTY_EAX30BUFFER_DIRECT
:
824 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
825 case DSPROPERTY_EAX30BUFFER_ROOM
:
826 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
827 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
828 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
829 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
830 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
831 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
832 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
833 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
834 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
835 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
836 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR
:
837 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR
:
838 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
839 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
840 case DSPROPERTY_EAX30BUFFER_FLAGS
:
841 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
845 FIXME("Unhandled propid: 0x%08lx\n", propid
);
847 return E_PROP_ID_UNSUPPORTED
;
851 HRESULT
EAX3Buffer_Set(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
855 if(buf
->filter
[0] == 0)
856 return E_PROP_ID_UNSUPPORTED
;
858 hr
= DSERR_INVALIDPARAM
;
861 case DSPROPERTY_EAX30BUFFER_NONE
: /* not setting any property, just applying */
865 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
866 if(cbPropData
>= sizeof(EAX30BUFFERPROPERTIES
))
870 const EAX30BUFFERPROPERTIES
*props
;
871 } data
= { pPropData
};
872 TRACE("Parameters:\n\tDirect: %ld\n\tDirect HF: %ld\n\tRoom: %ld\n\tRoom HF: %ld\n\t"
873 "Obstruction: %ld\n\tObstruction LF Ratio: %f\n\tOcclusion: %ld\n\t"
874 "Occlusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
875 "Occlusion Direct Ratio: %f\n\tExclusion: %ld\n\tExclusion LF Ratio: %f\n\t"
876 "Outside Volume HF: %ld\n\tDoppler Factor: %f\n\tRolloff Factor: %f\n\t"
877 "Room Rolloff Factor: %f\n\tAir Absorb Factor: %f\n\tFlags: 0x%02lx\n",
878 data
.props
->lDirect
, data
.props
->lDirectHF
, data
.props
->lRoom
, data
.props
->lRoomHF
,
879 data
.props
->lObstruction
, data
.props
->flObstructionLFRatio
, data
.props
->lOcclusion
,
880 data
.props
->flOcclusionLFRatio
, data
.props
->flOcclusionRoomRatio
,
881 data
.props
->flOcclusionDirectRatio
, data
.props
->lExclusion
,
882 data
.props
->flExclusionLFRatio
, data
.props
->lOutsideVolumeHF
,
883 data
.props
->flDopplerFactor
, data
.props
->flRolloffFactor
,
884 data
.props
->flRoomRolloffFactor
, data
.props
->flAirAbsorptionFactor
,
888 buf
->deferred
.eax
= *data
.props
;
889 ApplyFilterParams(buf
, data
.props
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
891 buf
->dirty
.bit
.dry_filter
= 1;
892 buf
->dirty
.bit
.wet_filter
= 1;
893 buf
->dirty
.bit
.room_rolloff
= 1;
894 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
895 buf
->dirty
.bit
.air_absorb
= 1;
896 buf
->dirty
.bit
.flags
= 1;
900 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS
:
901 if(cbPropData
>= sizeof(EAXOBSTRUCTIONPROPERTIES
))
905 const EAXOBSTRUCTIONPROPERTIES
*props
;
906 } data
= { pPropData
};
907 TRACE("Parameters:\n\tObstruction: %ld\n\tObstruction LF Ratio: %f\n",
908 data
.props
->lObstruction
, data
.props
->flObstructionLFRatio
);
910 buf
->deferred
.eax
.lObstruction
= data
.props
->lObstruction
;
911 buf
->deferred
.eax
.flObstructionLFRatio
= data
.props
->flObstructionLFRatio
;
912 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
914 buf
->dirty
.bit
.dry_filter
= 1;
918 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS
:
919 if(cbPropData
>= sizeof(EAXOCCLUSIONPROPERTIES
))
923 const EAXOCCLUSIONPROPERTIES
*props
;
924 } data
= { pPropData
};
925 TRACE("Parameters:\n\tOcclusion: %ld\n\tOcclusion LF Ratio: %f\n\t"
926 "Occlusion Room Ratio: %f\n\tOcclusion Direct Ratio: %f\n",
927 data
.props
->lOcclusion
, data
.props
->flOcclusionLFRatio
,
928 data
.props
->flOcclusionRoomRatio
, data
.props
->flOcclusionDirectRatio
931 buf
->deferred
.eax
.lOcclusion
= data
.props
->lOcclusion
;
932 buf
->deferred
.eax
.flOcclusionLFRatio
= data
.props
->flOcclusionLFRatio
;
933 buf
->deferred
.eax
.flOcclusionRoomRatio
= data
.props
->flOcclusionRoomRatio
;
934 buf
->deferred
.eax
.flOcclusionDirectRatio
= data
.props
->flOcclusionDirectRatio
;
935 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
937 buf
->dirty
.bit
.dry_filter
= 1;
938 buf
->dirty
.bit
.wet_filter
= 1;
942 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS
:
943 if(cbPropData
>= sizeof(EAXEXCLUSIONPROPERTIES
))
947 const EAXEXCLUSIONPROPERTIES
*props
;
948 } data
= { pPropData
};
949 TRACE("Parameters:\n\tExclusion: %ld\n\tExclusion LF Ratio: %f\n",
950 data
.props
->lExclusion
, data
.props
->flExclusionLFRatio
);
952 buf
->deferred
.eax
.lExclusion
= data
.props
->lExclusion
;
953 buf
->deferred
.eax
.flExclusionLFRatio
= data
.props
->flExclusionLFRatio
;
954 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
956 buf
->dirty
.bit
.wet_filter
= 1;
961 case DSPROPERTY_EAX30BUFFER_DIRECT
:
962 if(cbPropData
>= sizeof(long))
964 union { const void *v
; const long *l
; } data
= { pPropData
};
965 TRACE("Direct: %ld\n", *data
.l
);
967 buf
->deferred
.eax
.lDirect
= *data
.l
;
968 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
970 buf
->dirty
.bit
.dry_filter
= 1;
974 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
975 if(cbPropData
>= sizeof(long))
977 union { const void *v
; const long *l
; } data
= { pPropData
};
978 TRACE("Direct HF: %ld\n", *data
.l
);
980 buf
->deferred
.eax
.lDirectHF
= *data
.l
;
981 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
983 buf
->dirty
.bit
.dry_filter
= 1;
988 case DSPROPERTY_EAX30BUFFER_ROOM
:
989 if(cbPropData
>= sizeof(long))
991 union { const void *v
; const long *l
; } data
= { pPropData
};
992 TRACE("Room: %ld\n", *data
.l
);
994 buf
->deferred
.eax
.lRoom
= *data
.l
;
995 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
997 buf
->dirty
.bit
.wet_filter
= 1;
1001 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
1002 if(cbPropData
>= sizeof(long))
1004 union { const void *v
; const long *l
; } data
= { pPropData
};
1005 TRACE("Room HF: %ld\n", *data
.l
);
1007 buf
->deferred
.eax
.lRoomHF
= *data
.l
;
1008 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1010 buf
->dirty
.bit
.wet_filter
= 1;
1015 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
1016 if(cbPropData
>= sizeof(long))
1018 union { const void *v
; const long *l
; } data
= { pPropData
};
1019 TRACE("Obstruction: %ld\n", *data
.l
);
1021 buf
->deferred
.eax
.lObstruction
= *data
.l
;
1022 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1024 buf
->dirty
.bit
.dry_filter
= 1;
1028 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
1029 if(cbPropData
>= sizeof(float))
1031 union { const void *v
; const float *fl
; } data
= { pPropData
};
1032 TRACE("Obstruction LF Ratio: %f\n", *data
.fl
);
1034 buf
->deferred
.eax
.flObstructionLFRatio
= *data
.fl
;
1035 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1037 buf
->dirty
.bit
.dry_filter
= 1;
1042 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
1043 if(cbPropData
>= sizeof(long))
1045 union { const void *v
; const long *l
; } data
= { pPropData
};
1046 TRACE("Occlusion: %ld\n", *data
.l
);
1048 buf
->deferred
.eax
.lOcclusion
= *data
.l
;
1049 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1051 buf
->dirty
.bit
.dry_filter
= 1;
1052 buf
->dirty
.bit
.wet_filter
= 1;
1056 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
1057 if(cbPropData
>= sizeof(float))
1059 union { const void *v
; const float *fl
; } data
= { pPropData
};
1060 TRACE("Occlusion LF Ratio: %f\n", *data
.fl
);
1062 buf
->deferred
.eax
.flOcclusionLFRatio
= *data
.fl
;
1063 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1065 buf
->dirty
.bit
.dry_filter
= 1;
1066 buf
->dirty
.bit
.wet_filter
= 1;
1070 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
1071 if(cbPropData
>= sizeof(float))
1073 union { const void *v
; const float *fl
; } data
= { pPropData
};
1074 TRACE("Occlusion Room Ratio: %f\n", *data
.fl
);
1076 buf
->deferred
.eax
.flOcclusionRoomRatio
= *data
.fl
;
1077 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1079 buf
->dirty
.bit
.wet_filter
= 1;
1083 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
1084 if(cbPropData
>= sizeof(float))
1086 union { const void *v
; const float *fl
; } data
= { pPropData
};
1087 TRACE("Occlusion Direct Ratio: %f\n", *data
.fl
);
1089 buf
->deferred
.eax
.flOcclusionDirectRatio
= *data
.fl
;
1090 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1092 buf
->dirty
.bit
.dry_filter
= 1;
1097 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
1098 if(cbPropData
>= sizeof(long))
1100 union { const void *v
; const long *l
; } data
= { pPropData
};
1101 TRACE("Exclusion: %ld\n", *data
.l
);
1103 buf
->deferred
.eax
.lExclusion
= *data
.l
;
1104 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1106 buf
->dirty
.bit
.wet_filter
= 1;
1110 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
1111 if(cbPropData
>= sizeof(float))
1113 union { const void *v
; const float *fl
; } data
= { pPropData
};
1114 TRACE("Exclusion LF Ratio: %f\n", *data
.fl
);
1116 buf
->deferred
.eax
.flExclusionLFRatio
= *data
.fl
;
1117 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1119 buf
->dirty
.bit
.wet_filter
= 1;
1124 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
1125 if(cbPropData
>= sizeof(long))
1127 union { const void *v
; const long *l
; } data
= { pPropData
};
1128 TRACE("Outisde Volume HF: %ld\n", *data
.l
);
1130 buf
->deferred
.eax
.lOutsideVolumeHF
= *data
.l
;
1132 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
1137 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR
:
1138 if(cbPropData
>= sizeof(float))
1140 union { const void *v
; const float *fl
; } data
= { pPropData
};
1141 TRACE("Doppler Factor: %f\n", *data
.fl
);
1143 buf
->deferred
.eax
.flDopplerFactor
= *data
.fl
;
1145 buf
->dirty
.bit
.doppler
= 1;
1150 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR
:
1151 if(cbPropData
>= sizeof(float))
1153 union { const void *v
; const float *fl
; } data
= { pPropData
};
1154 TRACE("Rolloff Factor: %f\n", *data
.fl
);
1156 buf
->deferred
.eax
.flRolloffFactor
= *data
.fl
;
1158 buf
->dirty
.bit
.rolloff
= 1;
1163 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
1164 if(cbPropData
>= sizeof(float))
1166 union { const void *v
; const float *fl
; } data
= { pPropData
};
1167 TRACE("Room Rolloff Factor: %f\n", *data
.fl
);
1169 buf
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
1171 buf
->dirty
.bit
.room_rolloff
= 1;
1176 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
1177 if(cbPropData
>= sizeof(float))
1179 union { const void *v
; const float *fl
; } data
= { pPropData
};
1180 TRACE("Air Absorb Factor: %f\n", *data
.fl
);
1182 buf
->deferred
.eax
.flAirAbsorptionFactor
= *data
.fl
;
1184 buf
->dirty
.bit
.air_absorb
= 1;
1189 case DSPROPERTY_EAX30BUFFER_FLAGS
:
1190 if(cbPropData
>= sizeof(DWORD
))
1192 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1193 TRACE("Flags: 0x%lx\n", *data
.dw
);
1195 buf
->deferred
.eax
.dwFlags
= *data
.dw
;
1197 buf
->dirty
.bit
.flags
= 1;
1203 hr
= E_PROP_ID_UNSUPPORTED
;
1204 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1211 HRESULT
EAX3Buffer_Get(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
1215 if(buf
->filter
[0] == 0)
1216 return E_PROP_ID_UNSUPPORTED
;
1218 #define GET_PROP(src, T) do { \
1219 if(cbPropData >= sizeof(T)) \
1221 union { void *v; T *props; } data = { pPropData }; \
1222 *data.props = src; \
1223 *pcbReturned = sizeof(T); \
1227 hr
= DSERR_INVALIDPARAM
;
1230 case DSPROPERTY_EAX30BUFFER_NONE
:
1235 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
1236 GET_PROP(buf
->current
.eax
, EAX30BUFFERPROPERTIES
);
1238 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS
:
1239 GET_PROP(EAX3BufferObstruction(&buf
->current
.eax
), EAXOBSTRUCTIONPROPERTIES
);
1241 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS
:
1242 GET_PROP(EAX3BufferOcclusion(&buf
->current
.eax
), EAXOCCLUSIONPROPERTIES
);
1244 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS
:
1245 GET_PROP(EAX3BufferExclusion(&buf
->current
.eax
), EAXEXCLUSIONPROPERTIES
);
1248 case DSPROPERTY_EAX30BUFFER_DIRECT
:
1249 GET_PROP(buf
->current
.eax
.lDirect
, long);
1251 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
1252 GET_PROP(buf
->current
.eax
.lDirectHF
, long);
1255 case DSPROPERTY_EAX30BUFFER_ROOM
:
1256 GET_PROP(buf
->current
.eax
.lRoom
, long);
1258 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
1259 GET_PROP(buf
->current
.eax
.lRoomHF
, long);
1262 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
1263 GET_PROP(buf
->current
.eax
.lObstruction
, long);
1265 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
1266 GET_PROP(buf
->current
.eax
.flObstructionLFRatio
, float);
1269 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
1270 GET_PROP(buf
->current
.eax
.lOcclusion
, long);
1272 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
1273 GET_PROP(buf
->current
.eax
.flOcclusionLFRatio
, float);
1275 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
1276 GET_PROP(buf
->current
.eax
.flOcclusionRoomRatio
, float);
1278 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
1279 GET_PROP(buf
->current
.eax
.flOcclusionDirectRatio
, float);
1282 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
1283 GET_PROP(buf
->current
.eax
.lExclusion
, long);
1285 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
1286 GET_PROP(buf
->current
.eax
.flExclusionLFRatio
, float);
1289 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
1290 GET_PROP(buf
->current
.eax
.lOutsideVolumeHF
, long);
1293 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR
:
1294 GET_PROP(buf
->current
.eax
.flDopplerFactor
, float);
1297 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR
:
1298 GET_PROP(buf
->current
.eax
.flRolloffFactor
, float);
1300 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
1301 GET_PROP(buf
->current
.eax
.flRoomRolloffFactor
, float);
1304 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
1305 GET_PROP(buf
->current
.eax
.flAirAbsorptionFactor
, float);
1308 case DSPROPERTY_EAX30BUFFER_FLAGS
:
1309 GET_PROP(buf
->current
.eax
.dwFlags
, DWORD
);
1313 hr
= E_PROP_ID_UNSUPPORTED
;
1314 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1323 /*******************
1327 #define EAX2LISTENERFLAGS_MASK (EAX20LISTENERFLAGS_DECAYTIMESCALE | \
1328 EAX20LISTENERFLAGS_REFLECTIONSSCALE | \
1329 EAX20LISTENERFLAGS_REFLECTIONSDELAYSCALE | \
1330 EAX20LISTENERFLAGS_REVERBSCALE | \
1331 EAX20LISTENERFLAGS_REVERBDELAYSCALE | \
1332 EAX20LISTENERFLAGS_DECAYHFLIMIT)
1334 static EAX20LISTENERPROPERTIES
EAX3To2(const EAX30LISTENERPROPERTIES
*props
)
1336 EAX20LISTENERPROPERTIES ret
;
1337 ret
.lRoom
= props
->lRoom
;
1338 ret
.lRoomHF
= props
->lRoomHF
;
1339 ret
.flRoomRolloffFactor
= props
->flRoomRolloffFactor
;
1340 ret
.flDecayTime
= props
->flDecayTime
;
1341 ret
.flDecayHFRatio
= props
->flDecayHFRatio
;
1342 ret
.lReflections
= props
->lReflections
;
1343 ret
.flReflectionsDelay
= props
->flReflectionsDelay
;
1344 ret
.lReverb
= props
->lReverb
;
1345 ret
.flReverbDelay
= props
->flReverbDelay
;
1346 ret
.dwEnvironment
= props
->dwEnvironment
;
1347 ret
.flEnvironmentSize
= props
->flEnvironmentSize
;
1348 ret
.flEnvironmentDiffusion
= props
->flEnvironmentDiffusion
;
1349 ret
.flAirAbsorptionHF
= props
->flAirAbsorptionHF
;
1350 ret
.dwFlags
= props
->dwFlags
& EAX2LISTENERFLAGS_MASK
;
1354 static EAX20BUFFERPROPERTIES
EAXBuffer3To2(const EAX30BUFFERPROPERTIES
*props
)
1356 EAX20BUFFERPROPERTIES ret
;
1357 ret
.lDirect
= props
->lDirect
;
1358 ret
.lDirectHF
= props
->lDirectHF
;
1359 ret
.lRoom
= props
->lRoom
;
1360 ret
.lRoomHF
= props
->lRoomHF
;
1361 ret
.flRoomRolloffFactor
= props
->flRoomRolloffFactor
;
1362 ret
.lObstruction
= props
->lObstruction
;
1363 ret
.flObstructionLFRatio
= props
->flObstructionLFRatio
;
1364 ret
.lOcclusion
= props
->lOcclusion
;
1365 ret
.flOcclusionLFRatio
= props
->flOcclusionLFRatio
;
1366 ret
.flOcclusionRoomRatio
= props
->flOcclusionRoomRatio
;
1367 ret
.lOutsideVolumeHF
= props
->lOutsideVolumeHF
;
1368 ret
.flAirAbsorptionFactor
= props
->flAirAbsorptionFactor
;
1369 ret
.dwFlags
= props
->dwFlags
;
1374 HRESULT
EAX2_Query(DS8Primary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
1376 if(prim
->effect
== 0)
1377 return E_PROP_ID_UNSUPPORTED
;
1381 case DSPROPERTY_EAX20LISTENER_NONE
:
1382 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
1383 case DSPROPERTY_EAX20LISTENER_ROOM
:
1384 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
1385 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
1386 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
1387 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
1388 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
1389 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
1390 case DSPROPERTY_EAX20LISTENER_REVERB
:
1391 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
1392 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
1393 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
1394 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
1395 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
1396 case DSPROPERTY_EAX20LISTENER_FLAGS
:
1397 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
1401 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1403 return E_PROP_ID_UNSUPPORTED
;
1406 HRESULT
EAX2_Set(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
1410 if(prim
->effect
== 0)
1411 return E_PROP_ID_UNSUPPORTED
;
1413 hr
= DSERR_INVALIDPARAM
;
1416 case DSPROPERTY_EAX20LISTENER_NONE
: /* not setting any property, just applying */
1420 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
1421 if(cbPropData
>= sizeof(EAX20LISTENERPROPERTIES
))
1425 const EAX20LISTENERPROPERTIES
*props
;
1426 } data
= { pPropData
};
1427 EAX30LISTENERPROPERTIES props3
= REVERB_PRESET_GENERIC
;
1428 TRACE("Parameters:\n\tEnvironment: %lu\n\tEnvSize: %f\n\tEnvDiffusion: %f\n\t"
1429 "Room: %ld\n\tRoom HF: %ld\n\tDecay Time: %f\n\tDecay HF Ratio: %f\n\t"
1430 "Reflections: %ld\n\tReflections Delay: %f\n\tReverb: %ld\n\tReverb Delay: %f\n\t"
1431 "Air Absorption: %f\n\tRoom Rolloff: %f\n\tFlags: 0x%02lx\n",
1432 data
.props
->dwEnvironment
, data
.props
->flEnvironmentSize
,
1433 data
.props
->flEnvironmentDiffusion
, data
.props
->lRoom
, data
.props
->lRoomHF
,
1434 data
.props
->flDecayTime
, data
.props
->flDecayHFRatio
, data
.props
->lReflections
,
1435 data
.props
->flReflectionsDelay
, data
.props
->lReverb
, data
.props
->flReverbDelay
,
1436 data
.props
->flAirAbsorptionHF
, data
.props
->flRoomRolloffFactor
, data
.props
->dwFlags
1439 if(data
.props
->dwEnvironment
< EAX_ENVIRONMENT_UNDEFINED
)
1441 props3
= EnvironmentDefaults
[data
.props
->dwEnvironment
];
1442 props3
.dwEnvironment
= data
.props
->dwEnvironment
;
1444 props3
.flEnvironmentSize
= data
.props
->flEnvironmentSize
;
1445 props3
.flEnvironmentDiffusion
= data
.props
->flEnvironmentDiffusion
;
1446 props3
.lRoom
= data
.props
->lRoom
;
1447 props3
.lRoomHF
= data
.props
->lRoomHF
;
1448 props3
.flDecayTime
= data
.props
->flDecayTime
;
1449 props3
.flDecayHFRatio
= data
.props
->flDecayHFRatio
;
1450 props3
.lReflections
= data
.props
->lReflections
;
1451 props3
.flReflectionsDelay
= data
.props
->flReflectionsDelay
;
1452 props3
.lReverb
= data
.props
->lReverb
;
1453 props3
.flReverbDelay
= data
.props
->flReverbDelay
;
1454 props3
.flAirAbsorptionHF
= data
.props
->flAirAbsorptionHF
;
1455 props3
.flRoomRolloffFactor
= data
.props
->flRoomRolloffFactor
;
1456 props3
.dwFlags
= data
.props
->dwFlags
;
1458 ApplyReverbParams(prim
, &props3
);
1463 case DSPROPERTY_EAX20LISTENER_ROOM
:
1464 if(cbPropData
>= sizeof(long))
1466 union { const void *v
; const long *l
; } data
= { pPropData
};
1467 TRACE("Room: %ld\n", *data
.l
);
1469 prim
->deferred
.eax
.lRoom
= *data
.l
;
1470 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
,
1471 mB_to_gain(prim
->deferred
.eax
.lRoom
));
1474 prim
->dirty
.bit
.effect
= 1;
1478 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
1479 if(cbPropData
>= sizeof(long))
1481 union { const void *v
; const long *l
; } data
= { pPropData
};
1482 TRACE("Room HF: %ld\n", *data
.l
);
1484 prim
->deferred
.eax
.lRoomHF
= *data
.l
;
1485 alEffectf(prim
->effect
, AL_EAXREVERB_GAINHF
,
1486 mB_to_gain(prim
->deferred
.eax
.lRoomHF
));
1489 prim
->dirty
.bit
.effect
= 1;
1494 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
1495 if(cbPropData
>= sizeof(float))
1497 union { const void *v
; const float *fl
; } data
= { pPropData
};
1498 TRACE("Room Rolloff Factor: %f\n", *data
.fl
);
1500 prim
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
1501 alEffectf(prim
->effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
,
1502 prim
->deferred
.eax
.flRoomRolloffFactor
);
1505 prim
->dirty
.bit
.effect
= 1;
1510 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
1511 if(cbPropData
>= sizeof(float))
1513 union { const void *v
; const float *fl
; } data
= { pPropData
};
1514 TRACE("Decay Time: %f\n", *data
.fl
);
1516 prim
->deferred
.eax
.flDecayTime
= *data
.fl
;
1517 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
,
1518 prim
->deferred
.eax
.flDecayTime
);
1521 prim
->dirty
.bit
.effect
= 1;
1525 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
1526 if(cbPropData
>= sizeof(float))
1528 union { const void *v
; const float *fl
; } data
= { pPropData
};
1529 TRACE("Decay HF Ratio: %f\n", *data
.fl
);
1531 prim
->deferred
.eax
.flDecayHFRatio
= *data
.fl
;
1532 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_HFRATIO
,
1533 prim
->deferred
.eax
.flDecayHFRatio
);
1536 prim
->dirty
.bit
.effect
= 1;
1541 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
1542 if(cbPropData
>= sizeof(long))
1544 union { const void *v
; const long *l
; } data
= { pPropData
};
1545 TRACE("Reflections: %ld\n", *data
.l
);
1547 prim
->deferred
.eax
.lReflections
= *data
.l
;
1548 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_GAIN
,
1549 mB_to_gain(prim
->deferred
.eax
.lReflections
));
1552 prim
->dirty
.bit
.effect
= 1;
1556 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
1557 if(cbPropData
>= sizeof(float))
1559 union { const void *v
; const float *fl
; } data
= { pPropData
};
1560 TRACE("Reflections Delay: %f\n", *data
.fl
);
1562 prim
->deferred
.eax
.flReflectionsDelay
= *data
.fl
;
1563 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_DELAY
,
1564 prim
->deferred
.eax
.flReflectionsDelay
);
1567 prim
->dirty
.bit
.effect
= 1;
1572 case DSPROPERTY_EAX20LISTENER_REVERB
:
1573 if(cbPropData
>= sizeof(long))
1575 union { const void *v
; const long *l
; } data
= { pPropData
};
1576 TRACE("Reverb: %ld\n", *data
.l
);
1578 prim
->deferred
.eax
.lReverb
= *data
.l
;
1579 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_GAIN
,
1580 mB_to_gain(prim
->deferred
.eax
.lReverb
));
1583 prim
->dirty
.bit
.effect
= 1;
1587 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
1588 if(cbPropData
>= sizeof(float))
1590 union { const void *v
; const float *fl
; } data
= { pPropData
};
1591 TRACE("Reverb Delay: %f\n", *data
.fl
);
1593 prim
->deferred
.eax
.flReverbDelay
= *data
.fl
;
1594 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_DELAY
,
1595 prim
->deferred
.eax
.flReverbDelay
);
1598 prim
->dirty
.bit
.effect
= 1;
1603 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
1604 if(cbPropData
>= sizeof(DWORD
))
1606 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1607 TRACE("Environment: %lu\n", *data
.dw
);
1608 if(*data
.dw
< EAX_ENVIRONMENT_UNDEFINED
)
1610 ApplyReverbParams(prim
, &EnvironmentDefaults
[*data
.dw
]);
1616 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
1617 if(cbPropData
>= sizeof(float))
1619 union { const void *v
; const float *fl
; } data
= { pPropData
};
1620 TRACE("Environment Size: %f\n", *data
.fl
);
1622 RescaleEnvSize(&prim
->deferred
.eax
, clampF(*data
.fl
, 1.0f
, 100.0f
));
1624 ApplyReverbParams(prim
, &prim
->deferred
.eax
);
1628 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
1629 if(cbPropData
>= sizeof(float))
1631 union { const void *v
; const float *fl
; } data
= { pPropData
};
1632 TRACE("Environment Diffusion: %f\n", *data
.fl
);
1634 prim
->deferred
.eax
.flEnvironmentDiffusion
= *data
.fl
;
1635 alEffectf(prim
->effect
, AL_EAXREVERB_DIFFUSION
,
1636 prim
->deferred
.eax
.flEnvironmentDiffusion
);
1639 prim
->dirty
.bit
.effect
= 1;
1644 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
1645 if(cbPropData
>= sizeof(float))
1647 union { const void *v
; const float *fl
; } data
= { pPropData
};
1648 TRACE("Air Absorption HF: %f\n", *data
.fl
);
1650 prim
->deferred
.eax
.flAirAbsorptionHF
= *data
.fl
;
1651 alEffectf(prim
->effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
1652 mB_to_gain(prim
->deferred
.eax
.flAirAbsorptionHF
));
1655 prim
->dirty
.bit
.effect
= 1;
1660 case DSPROPERTY_EAX20LISTENER_FLAGS
:
1661 if(cbPropData
>= sizeof(DWORD
))
1663 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1664 TRACE("Flags: %lu\n", *data
.dw
);
1666 prim
->deferred
.eax
.dwFlags
= *data
.dw
;
1667 alEffecti(prim
->effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
1668 (prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
1669 AL_TRUE
: AL_FALSE
);
1672 prim
->dirty
.bit
.effect
= 1;
1678 hr
= E_PROP_ID_UNSUPPORTED
;
1679 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1686 HRESULT
EAX2_Get(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
1690 if(prim
->effect
== 0)
1691 return E_PROP_ID_UNSUPPORTED
;
1693 #define GET_PROP(src, T) do { \
1694 if(cbPropData >= sizeof(T)) \
1696 union { void *v; T *props; } data = { pPropData }; \
1697 *data.props = src; \
1698 *pcbReturned = sizeof(T); \
1702 hr
= DSERR_INVALIDPARAM
;
1705 case DSPROPERTY_EAX20LISTENER_NONE
:
1710 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
1711 GET_PROP(EAX3To2(&prim
->deferred
.eax
), EAX20LISTENERPROPERTIES
);
1714 case DSPROPERTY_EAX20LISTENER_ROOM
:
1715 GET_PROP(prim
->deferred
.eax
.lRoom
, long);
1717 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
1718 GET_PROP(prim
->deferred
.eax
.lRoomHF
, long);
1721 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
1722 GET_PROP(prim
->deferred
.eax
.flRoomRolloffFactor
, float);
1725 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
1726 GET_PROP(prim
->deferred
.eax
.flDecayTime
, float);
1728 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
1729 GET_PROP(prim
->deferred
.eax
.flDecayHFRatio
, float);
1732 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
1733 GET_PROP(prim
->deferred
.eax
.lReflections
, long);
1735 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
1736 GET_PROP(prim
->deferred
.eax
.flReflectionsDelay
, float);
1739 case DSPROPERTY_EAX20LISTENER_REVERB
:
1740 GET_PROP(prim
->deferred
.eax
.lReverb
, long);
1742 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
1743 GET_PROP(prim
->deferred
.eax
.flReverbDelay
, float);
1746 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
1747 GET_PROP(prim
->deferred
.eax
.dwEnvironment
, DWORD
);
1750 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
1751 GET_PROP(prim
->deferred
.eax
.flEnvironmentSize
, float);
1753 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
1754 GET_PROP(prim
->deferred
.eax
.flEnvironmentDiffusion
, float);
1757 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
1758 GET_PROP(prim
->deferred
.eax
.flAirAbsorptionHF
, float);
1761 case DSPROPERTY_EAX20LISTENER_FLAGS
:
1762 GET_PROP(prim
->deferred
.eax
.dwFlags
&EAX2LISTENERFLAGS_MASK
, DWORD
);
1766 hr
= E_PROP_ID_UNSUPPORTED
;
1767 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
1776 HRESULT
EAX2Buffer_Query(DS8Buffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
1778 if(buf
->filter
[0] == 0)
1779 return E_PROP_ID_UNSUPPORTED
;
1783 case DSPROPERTY_EAX20BUFFER_NONE
:
1784 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
1785 case DSPROPERTY_EAX20BUFFER_DIRECT
:
1786 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
1787 case DSPROPERTY_EAX20BUFFER_ROOM
:
1788 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
1789 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
1790 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
1791 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
1792 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
1793 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
1794 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
1795 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
1796 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
1797 case DSPROPERTY_EAX20BUFFER_FLAGS
:
1798 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
1802 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1804 return E_PROP_ID_UNSUPPORTED
;
1807 HRESULT
EAX2Buffer_Set(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
1811 if(buf
->filter
[0] == 0)
1812 return E_PROP_ID_UNSUPPORTED
;
1814 hr
= DSERR_INVALIDPARAM
;
1817 case DSPROPERTY_EAX20BUFFER_NONE
: /* not setting any property, just applying */
1821 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
1822 if(cbPropData
>= sizeof(EAX20BUFFERPROPERTIES
))
1826 const EAX20BUFFERPROPERTIES
*props
;
1827 } data
= { pPropData
};
1828 TRACE("Parameters:\n\tDirect: %ld\n\tDirect HF: %ld\n\tRoom: %ld\n\tRoom HF: %ld\n\t"
1829 "Room Rolloff Factor: %f\n\tObstruction: %ld\n\tObstruction LF Ratio: %f\n\t"
1830 "Occlusion: %ld\n\tOcclusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
1831 "Outside Volume HF: %ld\n\tAir Absorb Factor: %f\n\tFlags: 0x%02lx\n",
1832 data
.props
->lDirect
, data
.props
->lDirectHF
, data
.props
->lRoom
, data
.props
->lRoomHF
,
1833 data
.props
->flRoomRolloffFactor
, data
.props
->lObstruction
,
1834 data
.props
->flObstructionLFRatio
, data
.props
->lOcclusion
,
1835 data
.props
->flOcclusionLFRatio
, data
.props
->flOcclusionRoomRatio
,
1836 data
.props
->lOutsideVolumeHF
, data
.props
->flAirAbsorptionFactor
,
1840 buf
->deferred
.eax
.lDirect
= data
.props
->lDirect
;
1841 buf
->deferred
.eax
.lDirectHF
= data
.props
->lDirectHF
;
1842 buf
->deferred
.eax
.lRoom
= data
.props
->lRoom
;
1843 buf
->deferred
.eax
.lRoomHF
= data
.props
->lRoomHF
;
1844 buf
->deferred
.eax
.flRoomRolloffFactor
= data
.props
->flRoomRolloffFactor
;
1845 buf
->deferred
.eax
.lObstruction
= data
.props
->lObstruction
;
1846 buf
->deferred
.eax
.flObstructionLFRatio
= data
.props
->flObstructionLFRatio
;
1847 buf
->deferred
.eax
.lOcclusion
= data
.props
->lOcclusion
;
1848 buf
->deferred
.eax
.flOcclusionLFRatio
= data
.props
->flOcclusionLFRatio
;
1849 buf
->deferred
.eax
.flOcclusionRoomRatio
= data
.props
->flOcclusionRoomRatio
;
1850 buf
->deferred
.eax
.lOutsideVolumeHF
= data
.props
->lOutsideVolumeHF
;
1851 buf
->deferred
.eax
.flAirAbsorptionFactor
= data
.props
->flAirAbsorptionFactor
;
1852 buf
->deferred
.eax
.dwFlags
= data
.props
->dwFlags
;
1853 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1855 buf
->dirty
.bit
.dry_filter
= 1;
1856 buf
->dirty
.bit
.wet_filter
= 1;
1857 buf
->dirty
.bit
.room_rolloff
= 1;
1858 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
1859 buf
->dirty
.bit
.air_absorb
= 1;
1860 buf
->dirty
.bit
.flags
= 1;
1865 case DSPROPERTY_EAX20BUFFER_DIRECT
:
1866 if(cbPropData
>= sizeof(long))
1868 union { const void *v
; const long *l
; } data
= { pPropData
};
1869 TRACE("Direct: %ld\n", *data
.l
);
1871 buf
->deferred
.eax
.lDirect
= *data
.l
;
1872 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1874 buf
->dirty
.bit
.dry_filter
= 1;
1878 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
1879 if(cbPropData
>= sizeof(long))
1881 union { const void *v
; const long *l
; } data
= { pPropData
};
1882 TRACE("Direct HF: %ld\n", *data
.l
);
1884 buf
->deferred
.eax
.lDirectHF
= *data
.l
;
1885 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1887 buf
->dirty
.bit
.dry_filter
= 1;
1892 case DSPROPERTY_EAX20BUFFER_ROOM
:
1893 if(cbPropData
>= sizeof(long))
1895 union { const void *v
; const long *l
; } data
= { pPropData
};
1896 TRACE("Room: %ld\n", *data
.l
);
1898 buf
->deferred
.eax
.lRoom
= *data
.l
;
1899 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1901 buf
->dirty
.bit
.wet_filter
= 1;
1905 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
1906 if(cbPropData
>= sizeof(long))
1908 union { const void *v
; const long *l
; } data
= { pPropData
};
1909 TRACE("Room HF: %ld\n", *data
.l
);
1911 buf
->deferred
.eax
.lRoomHF
= *data
.l
;
1912 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1914 buf
->dirty
.bit
.wet_filter
= 1;
1919 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
1920 if(cbPropData
>= sizeof(float))
1922 union { const void *v
; const float *fl
; } data
= { pPropData
};
1923 TRACE("Room Rolloff Factor: %f\n", *data
.fl
);
1925 buf
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
1927 buf
->dirty
.bit
.room_rolloff
= 1;
1932 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
1933 if(cbPropData
>= sizeof(long))
1935 union { const void *v
; const long *l
; } data
= { pPropData
};
1936 TRACE("Obstruction: %ld\n", *data
.l
);
1938 buf
->deferred
.eax
.lObstruction
= *data
.l
;
1939 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1941 buf
->dirty
.bit
.dry_filter
= 1;
1945 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
1946 if(cbPropData
>= sizeof(float))
1948 union { const void *v
; const float *fl
; } data
= { pPropData
};
1949 TRACE("Obstruction LF Ratio: %f\n", *data
.fl
);
1951 buf
->deferred
.eax
.flObstructionLFRatio
= *data
.fl
;
1952 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1954 buf
->dirty
.bit
.dry_filter
= 1;
1959 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
1960 if(cbPropData
>= sizeof(long))
1962 union { const void *v
; const long *l
; } data
= { pPropData
};
1963 TRACE("Occlusion: %ld\n", *data
.l
);
1965 buf
->deferred
.eax
.lOcclusion
= *data
.l
;
1966 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1968 buf
->dirty
.bit
.dry_filter
= 1;
1969 buf
->dirty
.bit
.wet_filter
= 1;
1973 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
1974 if(cbPropData
>= sizeof(float))
1976 union { const void *v
; const float *fl
; } data
= { pPropData
};
1977 TRACE("Occlusion LF Ratio: %f\n", *data
.fl
);
1979 buf
->deferred
.eax
.flOcclusionLFRatio
= *data
.fl
;
1980 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1982 buf
->dirty
.bit
.dry_filter
= 1;
1983 buf
->dirty
.bit
.wet_filter
= 1;
1987 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
1988 if(cbPropData
>= sizeof(float))
1990 union { const void *v
; const float *fl
; } data
= { pPropData
};
1991 TRACE("Occlusion Room Ratio: %f\n", *data
.fl
);
1993 buf
->deferred
.eax
.flOcclusionRoomRatio
= *data
.fl
;
1994 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1996 buf
->dirty
.bit
.wet_filter
= 1;
2001 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
2002 if(cbPropData
>= sizeof(long))
2004 union { const void *v
; const long *l
; } data
= { pPropData
};
2005 TRACE("Outisde Volume HF: %ld\n", *data
.l
);
2007 buf
->deferred
.eax
.lOutsideVolumeHF
= *data
.l
;
2009 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
2014 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
2015 if(cbPropData
>= sizeof(float))
2017 union { const void *v
; const float *fl
; } data
= { pPropData
};
2018 TRACE("Air Absorb Factor: %f\n", *data
.fl
);
2020 buf
->deferred
.eax
.flAirAbsorptionFactor
= *data
.fl
;
2022 buf
->dirty
.bit
.air_absorb
= 1;
2027 case DSPROPERTY_EAX20BUFFER_FLAGS
:
2028 if(cbPropData
>= sizeof(DWORD
))
2030 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
2031 TRACE("Flags: 0x%lx\n", *data
.dw
);
2033 buf
->deferred
.eax
.dwFlags
= *data
.dw
;
2035 buf
->dirty
.bit
.flags
= 1;
2041 hr
= E_PROP_ID_UNSUPPORTED
;
2042 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2049 HRESULT
EAX2Buffer_Get(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
2053 if(buf
->filter
[0] == 0)
2054 return E_PROP_ID_UNSUPPORTED
;
2056 #define GET_PROP(src, T) do { \
2057 if(cbPropData >= sizeof(T)) \
2059 union { void *v; T *props; } data = { pPropData }; \
2060 *data.props = src; \
2061 *pcbReturned = sizeof(T); \
2065 hr
= DSERR_INVALIDPARAM
;
2068 case DSPROPERTY_EAX20BUFFER_NONE
:
2073 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
2074 GET_PROP(EAXBuffer3To2(&buf
->current
.eax
), EAX20BUFFERPROPERTIES
);
2077 case DSPROPERTY_EAX20BUFFER_DIRECT
:
2078 GET_PROP(buf
->current
.eax
.lDirect
, long);
2080 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
2081 GET_PROP(buf
->current
.eax
.lDirectHF
, long);
2084 case DSPROPERTY_EAX20BUFFER_ROOM
:
2085 GET_PROP(buf
->current
.eax
.lRoom
, long);
2087 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
2088 GET_PROP(buf
->current
.eax
.lRoomHF
, long);
2091 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
2092 GET_PROP(buf
->current
.eax
.flRoomRolloffFactor
, float);
2095 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
2096 GET_PROP(buf
->current
.eax
.lObstruction
, long);
2098 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
2099 GET_PROP(buf
->current
.eax
.flObstructionLFRatio
, float);
2102 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
2103 GET_PROP(buf
->current
.eax
.lOcclusion
, long);
2105 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
2106 GET_PROP(buf
->current
.eax
.flOcclusionLFRatio
, float);
2108 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
2109 GET_PROP(buf
->current
.eax
.flOcclusionRoomRatio
, float);
2112 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
2113 GET_PROP(buf
->current
.eax
.lOutsideVolumeHF
, long);
2116 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
2117 GET_PROP(buf
->current
.eax
.flAirAbsorptionFactor
, float);
2120 case DSPROPERTY_EAX20BUFFER_FLAGS
:
2121 GET_PROP(buf
->current
.eax
.dwFlags
, DWORD
);
2125 hr
= E_PROP_ID_UNSUPPORTED
;
2126 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2135 /*******************
2139 HRESULT
EAX1_Query(DS8Primary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
2141 if(prim
->effect
== 0)
2142 return E_PROP_ID_UNSUPPORTED
;
2146 case DSPROPERTY_EAX10LISTENER_ALL
:
2147 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT
:
2148 case DSPROPERTY_EAX10LISTENER_VOLUME
:
2149 case DSPROPERTY_EAX10LISTENER_DECAYTIME
:
2150 case DSPROPERTY_EAX10LISTENER_DAMPING
:
2151 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
2155 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2157 return E_PROP_ID_UNSUPPORTED
;
2160 HRESULT
EAX1_Set(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
2162 static const float eax1_env_volume
[EAX_ENVIRONMENT_UNDEFINED
] = {
2163 0.5f
, 0.25f
, 0.417f
, 0.653f
, 0.208f
, 0.5f
, 0.403f
, 0.5f
, 0.5f
,
2164 0.361f
, 0.5f
, 0.153f
, 0.361f
, 0.444f
, 0.25f
, 0.111f
, 0.111f
,
2165 0.194f
, 1.0f
, 0.097f
, 0.208f
, 0.652f
, 1.0f
, 0.875f
, 0.139f
, 0.486f
2167 static const float eax1_env_dampening
[EAX_ENVIRONMENT_UNDEFINED
] = {
2168 0.5f
, 0.0f
, 0.666f
, 0.166f
, 0.0f
, 0.888f
, 0.5f
, 0.5f
, 1.304f
,
2169 0.332f
, 0.3f
, 2.0f
, 0.0f
, 0.638f
, 0.776f
, 0.472f
, 0.224f
, 0.472f
,
2170 0.5f
, 0.224f
, 1.5f
, 0.25f
, 0.0f
, 1.388f
, 0.666f
, 0.806f
2174 if(prim
->effect
== 0)
2175 return E_PROP_ID_UNSUPPORTED
;
2177 hr
= DSERR_INVALIDPARAM
;
2180 case DSPROPERTY_EAX10LISTENER_ALL
:
2181 if(cbPropData
>= sizeof(EAX10LISTENERPROPERTIES
))
2185 const EAX10LISTENERPROPERTIES
*props
;
2186 } data
= { pPropData
};
2187 TRACE("Parameters:\n\tEnvironment: %lu\n\tVolume: %f\n\tDecay Time: %f\n\t"
2188 "Damping: %f\n", data
.props
->dwEnvironment
, data
.props
->fVolume
,
2189 data
.props
->fDecayTime
, data
.props
->fDamping
2192 if(data
.props
->dwEnvironment
< EAX_ENVIRONMENT_UNDEFINED
)
2194 /* NOTE: I'm not quite sure how to handle the volume. It's
2195 * important to deal with since it can have a notable impact on
2196 * the output levels, but given the default EAX1 environment
2197 * volumes, they don't align with the gain/room volume for
2198 * EAX2+ environments. Presuming the default volumes are
2199 * correct, it's possible the reverb implementation was
2200 * different and relied on different gains to get the intended
2203 * Rather than just blindly applying the volume, we take the
2204 * difference from the EAX1 environment's default volume and
2205 * apply that as an offset to the EAX2 environment's volume.
2207 EAX30LISTENERPROPERTIES env
= EnvironmentDefaults
[data
.props
->dwEnvironment
];
2208 long db_vol
= clampI(
2209 gain_to_mB(data
.props
->fVolume
/ eax1_env_volume
[data
.props
->dwEnvironment
]),
2212 env
.lRoom
= clampI(env
.lRoom
+ db_vol
, -10000, 0);
2213 env
.flDecayTime
= data
.props
->fDecayTime
;
2214 prim
->deferred
.eax1_volume
= data
.props
->fVolume
;
2215 prim
->deferred
.eax1_dampening
= data
.props
->fDamping
;
2216 ApplyReverbParams(prim
, &env
);
2222 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT
:
2223 if(cbPropData
>= sizeof(DWORD
))
2225 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
2226 TRACE("Environment: %lu\n", *data
.dw
);
2228 if(*data
.dw
< EAX_ENVIRONMENT_UNDEFINED
)
2230 prim
->deferred
.eax1_volume
= eax1_env_volume
[*data
.dw
];
2231 prim
->deferred
.eax1_dampening
= eax1_env_dampening
[*data
.dw
];
2232 ApplyReverbParams(prim
, &EnvironmentDefaults
[*data
.dw
]);
2238 case DSPROPERTY_EAX10LISTENER_VOLUME
:
2239 if(cbPropData
>= sizeof(float))
2241 union { const void *v
; const float *fl
; } data
= { pPropData
};
2242 long db_vol
= clampI(
2243 gain_to_mB(*data
.fl
/ eax1_env_volume
[prim
->deferred
.eax
.dwEnvironment
]),
2246 long room_vol
= clampI(
2247 EnvironmentDefaults
[prim
->deferred
.eax
.dwEnvironment
].lRoom
+ db_vol
,
2250 TRACE("Volume: %f\n", *data
.fl
);
2252 prim
->deferred
.eax
.lRoom
= room_vol
;
2253 prim
->deferred
.eax1_volume
= *data
.fl
;
2254 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
, mB_to_gain(room_vol
));
2257 prim
->dirty
.bit
.effect
= 1;
2261 case DSPROPERTY_EAX10LISTENER_DECAYTIME
:
2262 if(cbPropData
>= sizeof(float))
2264 union { const void *v
; const float *fl
; } data
= { pPropData
};
2265 TRACE("Decay Time: %f\n", *data
.fl
);
2267 prim
->deferred
.eax
.flDecayTime
= *data
.fl
;
2268 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
,
2269 prim
->deferred
.eax
.flDecayTime
);
2272 prim
->dirty
.bit
.effect
= 1;
2276 case DSPROPERTY_EAX10LISTENER_DAMPING
:
2277 if(cbPropData
>= sizeof(float))
2279 union { const void *v
; const float *fl
; } data
= { pPropData
};
2280 TRACE("Damping: %f\n", *data
.fl
);
2282 prim
->deferred
.eax1_dampening
= *data
.fl
;
2289 hr
= E_PROP_ID_UNSUPPORTED
;
2290 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2297 HRESULT
EAX1_Get(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
2301 if(prim
->effect
== 0)
2302 return E_PROP_ID_UNSUPPORTED
;
2304 hr
= DSERR_INVALIDPARAM
;
2307 case DSPROPERTY_EAX10LISTENER_ALL
:
2308 if(cbPropData
>= sizeof(EAX10LISTENERPROPERTIES
))
2312 EAX10LISTENERPROPERTIES
*props
;
2313 } data
= { pPropData
};
2315 data
.props
->dwEnvironment
= prim
->deferred
.eax
.dwEnvironment
;
2316 data
.props
->fVolume
= prim
->deferred
.eax1_volume
;
2317 data
.props
->fDecayTime
= prim
->deferred
.eax
.flDecayTime
;
2318 data
.props
->fDamping
= prim
->deferred
.eax1_dampening
;
2320 *pcbReturned
= sizeof(EAX10LISTENERPROPERTIES
);
2325 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT
:
2326 if(cbPropData
>= sizeof(DWORD
))
2328 union { void *v
; DWORD
*dw
; } data
= { pPropData
};
2330 *data
.dw
= prim
->deferred
.eax
.dwEnvironment
;
2332 *pcbReturned
= sizeof(DWORD
);
2337 case DSPROPERTY_EAX10LISTENER_VOLUME
:
2338 if(cbPropData
>= sizeof(float))
2340 union { void *v
; float *fl
; } data
= { pPropData
};
2342 *data
.fl
= prim
->deferred
.eax1_volume
;
2344 *pcbReturned
= sizeof(float);
2349 case DSPROPERTY_EAX10LISTENER_DECAYTIME
:
2350 if(cbPropData
>= sizeof(float))
2352 union { void *v
; float *fl
; } data
= { pPropData
};
2354 *data
.fl
= prim
->deferred
.eax
.flDecayTime
;
2356 *pcbReturned
= sizeof(float);
2361 case DSPROPERTY_EAX10LISTENER_DAMPING
:
2362 if(cbPropData
>= sizeof(float))
2364 union { void *v
; float *fl
; } data
= { pPropData
};
2366 *data
.fl
= prim
->deferred
.eax1_dampening
;
2368 *pcbReturned
= sizeof(float);
2374 hr
= E_PROP_ID_UNSUPPORTED
;
2375 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2383 HRESULT
EAX1Buffer_Query(DS8Buffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
2385 if(buf
->filter
[0] == 0)
2386 return E_PROP_ID_UNSUPPORTED
;
2390 case DSPROPERTY_EAX10BUFFER_ALL
:
2391 case DSPROPERTY_EAX10BUFFER_REVERBMIX
:
2392 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
2396 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2398 return E_PROP_ID_UNSUPPORTED
;
2401 HRESULT
EAX1Buffer_Set(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
2405 if(buf
->filter
[0] == 0)
2406 return E_PROP_ID_UNSUPPORTED
;
2408 hr
= DSERR_INVALIDPARAM
;
2411 /* NOTE: DSPROPERTY_EAX10BUFFER_ALL is for EAX10BUFFERPROPERTIES, however
2412 * that struct just contains the single ReverbMix float property.
2414 case DSPROPERTY_EAX10BUFFER_ALL
:
2415 case DSPROPERTY_EAX10BUFFER_REVERBMIX
:
2416 if(cbPropData
>= sizeof(float))
2418 union { const void *v
; const float *fl
; } data
= { pPropData
};
2419 TRACE("Reverb Mix: %f\n", *data
.fl
);
2421 buf
->deferred
.eax
.lRoom
= gain_to_mB(*data
.fl
);
2422 buf
->deferred
.eax1_reverbmix
= *data
.fl
;
2423 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
2425 buf
->dirty
.bit
.wet_filter
= 1;
2431 hr
= E_PROP_ID_UNSUPPORTED
;
2432 FIXME("Unhandled propid: 0x%08lx\n", propid
);
2439 HRESULT
EAX1Buffer_Get(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
2443 if(buf
->filter
[0] == 0)
2444 return E_PROP_ID_UNSUPPORTED
;
2446 hr
= DSERR_INVALIDPARAM
;
2449 case DSPROPERTY_EAX10BUFFER_ALL
:
2450 case DSPROPERTY_EAX10BUFFER_REVERBMIX
:
2451 if(cbPropData
>= sizeof(float))
2453 union { void *v
; float *fl
; } data
= { pPropData
};
2455 *data
.fl
= buf
->current
.eax1_reverbmix
;
2456 *pcbReturned
= sizeof(float);
2462 hr
= E_PROP_ID_UNSUPPORTED
;
2463 FIXME("Unhandled propid: 0x%08lx\n", propid
);