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"
28 static void ApplyReverbParams(DS8Primary
*prim
, const EAX30LISTENERPROPERTIES
*props
)
30 /* FIXME: Need to validate property values... Ignore? Clamp? Error? */
31 prim
->deferred
.eax
= *props
;
32 alEffectf(prim
->effect
, AL_EAXREVERB_DENSITY
,
33 clampF(powf(props
->flEnvironmentSize
, 3.0f
) / 16.0f
, 0.0f
, 1.0f
)
35 alEffectf(prim
->effect
, AL_EAXREVERB_DIFFUSION
, props
->flEnvironmentDiffusion
);
37 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
, mB_to_gain(props
->lRoom
));
38 alEffectf(prim
->effect
, AL_EAXREVERB_GAINHF
, mB_to_gain(props
->lRoomHF
));
39 alEffectf(prim
->effect
, AL_EAXREVERB_GAINLF
, mB_to_gain(props
->lRoomLF
));
41 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
, props
->flDecayTime
);
42 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_HFRATIO
, props
->flDecayHFRatio
);
43 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_LFRATIO
, props
->flDecayLFRatio
);
45 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_GAIN
, mB_to_gain(props
->lReflections
));
46 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_DELAY
, props
->flReflectionsDelay
);
47 alEffectfv(prim
->effect
, AL_EAXREVERB_REFLECTIONS_PAN
, &props
->vReflectionsPan
.x
);
49 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_GAIN
, mB_to_gain(props
->lReverb
));
50 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_DELAY
, props
->flReverbDelay
);
51 alEffectfv(prim
->effect
, AL_EAXREVERB_LATE_REVERB_PAN
, &props
->vReverbPan
.x
);
53 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_TIME
, props
->flEchoTime
);
54 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_DEPTH
, props
->flEchoDepth
);
56 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_TIME
, props
->flModulationTime
);
57 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_DEPTH
, props
->flModulationDepth
);
59 alEffectf(prim
->effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
60 mB_to_gain(props
->flAirAbsorptionHF
));
62 alEffectf(prim
->effect
, AL_EAXREVERB_HFREFERENCE
, props
->flHFReference
);
63 alEffectf(prim
->effect
, AL_EAXREVERB_LFREFERENCE
, props
->flLFReference
);
65 alEffectf(prim
->effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
, props
->flRoomRolloffFactor
);
67 alEffecti(prim
->effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
68 (props
->dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
73 prim
->dirty
.bit
.effect
= 1;
76 #define APPLY_DRY_PARAMS 1
77 #define APPLY_WET_PARAMS 2
78 static void ApplyFilterParams(DS8Buffer
*buf
, const EAX30BUFFERPROPERTIES
*props
, int apply
)
80 /* The LFRatio properties determine how much the given level applies to low
81 * frequencies as well as high frequencies. Given that the high frequency
82 * levels are specified relative to the low, they should increase as the
83 * low frequency levels reduce.
85 FLOAT occl
= props
->lOcclusion
* props
->flOcclusionLFRatio
;
86 FLOAT occlhf
= props
->lOcclusion
* (1.0f
-props
->flOcclusionLFRatio
);
88 if((apply
&APPLY_DRY_PARAMS
))
90 FLOAT obstr
= props
->lObstruction
* props
->flObstructionLFRatio
;
91 FLOAT obstrhf
= props
->lObstruction
* (1.0f
-props
->flObstructionLFRatio
);
92 FLOAT occldirect
= props
->flOcclusionDirectRatio
;
93 FLOAT mb
= props
->lDirect
+ obstr
+ occldirect
*occl
;
94 FLOAT mbhf
= props
->lDirectHF
+ obstrhf
+ occldirect
*occlhf
;
96 alFilterf(buf
->filter
[0], AL_LOWPASS_GAIN
, clampF(mB_to_gain(mb
), 0.0f
, 1.0f
));
97 alFilterf(buf
->filter
[0], AL_LOWPASS_GAINHF
, clampF(mB_to_gain(mbhf
), 0.0f
, 1.0f
));
99 if((apply
&APPLY_WET_PARAMS
))
101 FLOAT excl
= props
->lExclusion
* props
->flExclusionLFRatio
;
102 FLOAT exclhf
= props
->lExclusion
* (1.0f
-props
->flExclusionLFRatio
);
103 FLOAT occlroom
= props
->flOcclusionRoomRatio
;
104 FLOAT mb
= props
->lRoom
+ excl
+ occlroom
*occl
;
105 FLOAT mbhf
= props
->lRoomHF
+ exclhf
+ occlroom
*occlhf
;
107 alFilterf(buf
->filter
[1], AL_LOWPASS_GAIN
, clampF(mB_to_gain(mb
), 0.0f
, 1.0f
));
108 alFilterf(buf
->filter
[1], AL_LOWPASS_GAINHF
, clampF(mB_to_gain(mbhf
), 0.0f
, 1.0f
));
118 HRESULT
EAX3_Set(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
122 if(prim
->effect
== 0)
123 return E_PROP_ID_UNSUPPORTED
;
125 hr
= DSERR_INVALIDPARAM
;
128 case DSPROPERTY_EAX30LISTENER_NONE
: /* not setting any property, just applying */
132 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
133 if(cbPropData
>= sizeof(EAX30LISTENERPROPERTIES
))
137 const EAX30LISTENERPROPERTIES
*props
;
138 } data
= { pPropData
};
140 /* FIXME: There's some unknown behavior here. When RightMark3DSound
141 * deals with environment panning and morphing, the current preset
142 * ID will sometimes be repeated, which seems to expect some
143 * parameters to stay unmodified. Other cases see preset ID 26,
144 * which is out of range. I'm not sure how these values are
145 * supposed to be treated.
147 ApplyReverbParams(prim
, data
.props
);
152 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
153 if(cbPropData
>= sizeof(DWORD
))
155 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
156 if(*data
.dw
< EAX_ENVIRONMENT_COUNT
)
158 ApplyReverbParams(prim
, &EnvironmentDefaults
[*data
.dw
]);
164 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
165 if(cbPropData
>= sizeof(FLOAT
))
167 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
168 if(*data
.fl
>= 1.0f
&& *data
.fl
<= 100.0f
)
170 float scale
= (*data
.fl
)/prim
->deferred
.eax
.flEnvironmentSize
;
172 prim
->deferred
.eax
.flEnvironmentSize
= *data
.fl
;
174 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_DECAYTIMESCALE
))
176 prim
->deferred
.eax
.flDecayTime
*= scale
;
177 prim
->deferred
.eax
.flDecayTime
= clampF(prim
->deferred
.eax
.flDecayTime
, 0.1f
, 20.0f
);
179 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSSCALE
))
181 prim
->deferred
.eax
.lReflections
-= gain_to_mB(scale
);
182 prim
->deferred
.eax
.lReflections
= clampI(prim
->deferred
.eax
.lReflections
, -10000, 1000);
184 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSDELAYSCALE
))
186 prim
->deferred
.eax
.flReflectionsDelay
*= scale
;
187 prim
->deferred
.eax
.flReflectionsDelay
= clampF(prim
->deferred
.eax
.flReflectionsDelay
, 0.0f
, 0.3f
);
189 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REVERBSCALE
))
191 prim
->deferred
.eax
.lReverb
-= gain_to_mB(scale
);
192 prim
->deferred
.eax
.lReverb
= clampI(prim
->deferred
.eax
.lReverb
, -10000, 2000);
194 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REVERBDELAYSCALE
))
196 prim
->deferred
.eax
.flReverbDelay
*= scale
;
197 prim
->deferred
.eax
.flReverbDelay
= clampF(prim
->deferred
.eax
.flReverbDelay
, 0.0f
, 0.1f
);
199 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_ECHOTIMESCALE
))
201 prim
->deferred
.eax
.flEchoTime
*= scale
;
202 prim
->deferred
.eax
.flEchoTime
= clampF(prim
->deferred
.eax
.flEchoTime
, 0.075f
, 0.25f
);
204 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_MODTIMESCALE
))
206 prim
->deferred
.eax
.flModulationTime
*= scale
;
207 prim
->deferred
.eax
.flModulationTime
= clampF(prim
->deferred
.eax
.flModulationTime
, 0.04f
, 4.0f
);
210 ApplyReverbParams(prim
, &prim
->deferred
.eax
);
215 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
216 if(cbPropData
>= sizeof(FLOAT
))
218 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
220 prim
->deferred
.eax
.flEnvironmentDiffusion
= *data
.fl
;
221 alEffectf(prim
->effect
, AL_EAXREVERB_DIFFUSION
,
222 prim
->deferred
.eax
.flEnvironmentDiffusion
);
225 prim
->dirty
.bit
.effect
= 1;
230 case DSPROPERTY_EAX30LISTENER_ROOM
:
231 if(cbPropData
>= sizeof(LONG
))
233 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
235 prim
->deferred
.eax
.lRoom
= *data
.l
;
236 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
,
237 mB_to_gain(prim
->deferred
.eax
.lRoom
));
240 prim
->dirty
.bit
.effect
= 1;
244 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
245 if(cbPropData
>= sizeof(LONG
))
247 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
249 prim
->deferred
.eax
.lRoomHF
= *data
.l
;
250 alEffectf(prim
->effect
, AL_EAXREVERB_GAINHF
,
251 mB_to_gain(prim
->deferred
.eax
.lRoomHF
));
254 prim
->dirty
.bit
.effect
= 1;
258 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
259 if(cbPropData
>= sizeof(LONG
))
261 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
263 prim
->deferred
.eax
.lRoomLF
= *data
.l
;
264 alEffectf(prim
->effect
, AL_EAXREVERB_GAINLF
,
265 mB_to_gain(prim
->deferred
.eax
.lRoomLF
));
268 prim
->dirty
.bit
.effect
= 1;
273 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
274 if(cbPropData
>= sizeof(FLOAT
))
276 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
278 prim
->deferred
.eax
.flDecayTime
= *data
.fl
;
279 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
,
280 prim
->deferred
.eax
.flDecayTime
);
283 prim
->dirty
.bit
.effect
= 1;
287 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
288 if(cbPropData
>= sizeof(FLOAT
))
290 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
292 prim
->deferred
.eax
.flDecayHFRatio
= *data
.fl
;
293 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_HFRATIO
,
294 prim
->deferred
.eax
.flDecayHFRatio
);
297 prim
->dirty
.bit
.effect
= 1;
301 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
302 if(cbPropData
>= sizeof(FLOAT
))
304 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
306 prim
->deferred
.eax
.flDecayLFRatio
= *data
.fl
;
307 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_LFRATIO
,
308 prim
->deferred
.eax
.flDecayLFRatio
);
311 prim
->dirty
.bit
.effect
= 1;
316 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
317 if(cbPropData
>= sizeof(LONG
))
319 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
321 prim
->deferred
.eax
.lReflections
= *data
.l
;
322 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_GAIN
,
323 mB_to_gain(prim
->deferred
.eax
.lReflections
));
326 prim
->dirty
.bit
.effect
= 1;
330 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
331 if(cbPropData
>= sizeof(FLOAT
))
333 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
335 prim
->deferred
.eax
.flReflectionsDelay
= *data
.fl
;
336 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_DELAY
,
337 prim
->deferred
.eax
.flReflectionsDelay
);
340 prim
->dirty
.bit
.effect
= 1;
344 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
345 if(cbPropData
>= sizeof(EAXVECTOR
))
347 union { const void *v
; const EAXVECTOR
*vec
; } data
= { pPropData
};
349 prim
->deferred
.eax
.vReflectionsPan
= *data
.vec
;
350 alEffectfv(prim
->effect
, AL_EAXREVERB_REFLECTIONS_PAN
,
351 &prim
->deferred
.eax
.vReflectionsPan
.x
);
354 prim
->dirty
.bit
.effect
= 1;
359 case DSPROPERTY_EAX30LISTENER_REVERB
:
360 if(cbPropData
>= sizeof(LONG
))
362 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
364 prim
->deferred
.eax
.lReverb
= *data
.l
;
365 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_GAIN
,
366 mB_to_gain(prim
->deferred
.eax
.lReverb
));
369 prim
->dirty
.bit
.effect
= 1;
373 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
374 if(cbPropData
>= sizeof(FLOAT
))
376 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
378 prim
->deferred
.eax
.flReverbDelay
= *data
.fl
;
379 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_DELAY
,
380 prim
->deferred
.eax
.flReverbDelay
);
383 prim
->dirty
.bit
.effect
= 1;
387 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
388 if(cbPropData
>= sizeof(EAXVECTOR
))
390 union { const void *v
; const EAXVECTOR
*vec
; } data
= { pPropData
};
392 prim
->deferred
.eax
.vReverbPan
= *data
.vec
;
393 alEffectfv(prim
->effect
, AL_EAXREVERB_LATE_REVERB_PAN
,
394 &prim
->deferred
.eax
.vReverbPan
.x
);
397 prim
->dirty
.bit
.effect
= 1;
402 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
403 if(cbPropData
>= sizeof(FLOAT
))
405 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
407 prim
->deferred
.eax
.flEchoTime
= *data
.fl
;
408 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_TIME
,
409 prim
->deferred
.eax
.flEchoTime
);
412 prim
->dirty
.bit
.effect
= 1;
416 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
417 if(cbPropData
>= sizeof(FLOAT
))
419 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
421 prim
->deferred
.eax
.flEchoDepth
= *data
.fl
;
422 alEffectf(prim
->effect
, AL_EAXREVERB_ECHO_DEPTH
,
423 prim
->deferred
.eax
.flEchoDepth
);
426 prim
->dirty
.bit
.effect
= 1;
431 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
432 if(cbPropData
>= sizeof(FLOAT
))
434 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
436 prim
->deferred
.eax
.flModulationTime
= *data
.fl
;
437 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_TIME
,
438 prim
->deferred
.eax
.flModulationTime
);
441 prim
->dirty
.bit
.effect
= 1;
445 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
446 if(cbPropData
>= sizeof(FLOAT
))
448 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
450 prim
->deferred
.eax
.flModulationDepth
= *data
.fl
;
451 alEffectf(prim
->effect
, AL_EAXREVERB_MODULATION_DEPTH
,
452 prim
->deferred
.eax
.flModulationDepth
);
455 prim
->dirty
.bit
.effect
= 1;
460 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
461 if(cbPropData
>= sizeof(FLOAT
))
463 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
465 prim
->deferred
.eax
.flAirAbsorptionHF
= *data
.fl
;
466 alEffectf(prim
->effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
467 mB_to_gain(prim
->deferred
.eax
.flAirAbsorptionHF
));
470 prim
->dirty
.bit
.effect
= 1;
475 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
476 if(cbPropData
>= sizeof(FLOAT
))
478 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
480 prim
->deferred
.eax
.flHFReference
= *data
.fl
;
481 alEffectf(prim
->effect
, AL_EAXREVERB_HFREFERENCE
,
482 prim
->deferred
.eax
.flHFReference
);
485 prim
->dirty
.bit
.effect
= 1;
489 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
490 if(cbPropData
>= sizeof(FLOAT
))
492 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
494 prim
->deferred
.eax
.flLFReference
= *data
.fl
;
495 alEffectf(prim
->effect
, AL_EAXREVERB_LFREFERENCE
,
496 prim
->deferred
.eax
.flLFReference
);
499 prim
->dirty
.bit
.effect
= 1;
504 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
505 if(cbPropData
>= sizeof(FLOAT
))
507 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
509 prim
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
510 alEffectf(prim
->effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
,
511 prim
->deferred
.eax
.flRoomRolloffFactor
);
514 prim
->dirty
.bit
.effect
= 1;
519 case DSPROPERTY_EAX30LISTENER_FLAGS
:
520 if(cbPropData
>= sizeof(DWORD
))
522 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
524 prim
->deferred
.eax
.dwFlags
= *data
.dw
;
525 alEffecti(prim
->effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
526 (prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
530 prim
->dirty
.bit
.effect
= 1;
536 hr
= E_PROP_ID_UNSUPPORTED
;
537 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
544 HRESULT
EAX3_Get(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
548 if(prim
->effect
== 0)
549 return E_PROP_ID_UNSUPPORTED
;
551 #define GET_PROP(src, T) do { \
552 if(cbPropData >= sizeof(T)) \
554 union { void *v; T *props; } data = { pPropData }; \
556 *pcbReturned = sizeof(T); \
560 hr
= DSERR_INVALIDPARAM
;
563 case DSPROPERTY_EAX30LISTENER_NONE
:
568 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS
:
569 GET_PROP(prim
->deferred
.eax
, EAX30LISTENERPROPERTIES
);
572 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT
:
573 GET_PROP(prim
->deferred
.eax
.dwEnvironment
, DWORD
);
576 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE
:
577 GET_PROP(prim
->deferred
.eax
.flEnvironmentSize
, FLOAT
);
579 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION
:
580 GET_PROP(prim
->deferred
.eax
.flEnvironmentDiffusion
, FLOAT
);
583 case DSPROPERTY_EAX30LISTENER_ROOM
:
584 GET_PROP(prim
->deferred
.eax
.lRoom
, LONG
);
586 case DSPROPERTY_EAX30LISTENER_ROOMHF
:
587 GET_PROP(prim
->deferred
.eax
.lRoomHF
, LONG
);
589 case DSPROPERTY_EAX30LISTENER_ROOMLF
:
590 GET_PROP(prim
->deferred
.eax
.lRoomLF
, LONG
);
593 case DSPROPERTY_EAX30LISTENER_DECAYTIME
:
594 GET_PROP(prim
->deferred
.eax
.flDecayTime
, FLOAT
);
596 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO
:
597 GET_PROP(prim
->deferred
.eax
.flDecayHFRatio
, FLOAT
);
599 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO
:
600 GET_PROP(prim
->deferred
.eax
.flDecayLFRatio
, FLOAT
);
603 case DSPROPERTY_EAX30LISTENER_REFLECTIONS
:
604 GET_PROP(prim
->deferred
.eax
.lReflections
, LONG
);
606 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY
:
607 GET_PROP(prim
->deferred
.eax
.flReflectionsDelay
, FLOAT
);
609 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN
:
610 GET_PROP(prim
->deferred
.eax
.vReflectionsPan
, EAXVECTOR
);
613 case DSPROPERTY_EAX30LISTENER_REVERB
:
614 GET_PROP(prim
->deferred
.eax
.lReverb
, LONG
);
616 case DSPROPERTY_EAX30LISTENER_REVERBDELAY
:
617 GET_PROP(prim
->deferred
.eax
.flReverbDelay
, FLOAT
);
619 case DSPROPERTY_EAX30LISTENER_REVERBPAN
:
620 GET_PROP(prim
->deferred
.eax
.vReverbPan
, EAXVECTOR
);
623 case DSPROPERTY_EAX30LISTENER_ECHOTIME
:
624 GET_PROP(prim
->deferred
.eax
.flEchoTime
, FLOAT
);
626 case DSPROPERTY_EAX30LISTENER_ECHODEPTH
:
627 GET_PROP(prim
->deferred
.eax
.flEchoDepth
, FLOAT
);
630 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME
:
631 GET_PROP(prim
->deferred
.eax
.flModulationTime
, FLOAT
);
633 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH
:
634 GET_PROP(prim
->deferred
.eax
.flModulationDepth
, FLOAT
);
637 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF
:
638 GET_PROP(prim
->deferred
.eax
.flAirAbsorptionHF
, FLOAT
);
641 case DSPROPERTY_EAX30LISTENER_HFREFERENCE
:
642 GET_PROP(prim
->deferred
.eax
.flHFReference
, FLOAT
);
644 case DSPROPERTY_EAX30LISTENER_LFREFERENCE
:
645 GET_PROP(prim
->deferred
.eax
.flLFReference
, FLOAT
);
648 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR
:
649 GET_PROP(prim
->deferred
.eax
.flRoomRolloffFactor
, FLOAT
);
652 case DSPROPERTY_EAX30LISTENER_FLAGS
:
653 GET_PROP(prim
->deferred
.eax
.dwFlags
, DWORD
);
657 hr
= E_PROP_ID_UNSUPPORTED
;
658 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
666 HRESULT
EAX3Buffer_Set(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
670 if(buf
->filter
[0] == 0)
671 return E_PROP_ID_UNSUPPORTED
;
673 hr
= DSERR_INVALIDPARAM
;
676 case DSPROPERTY_EAX30BUFFER_NONE
: /* not setting any property, just applying */
680 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
681 if(cbPropData
>= sizeof(EAX30BUFFERPROPERTIES
))
685 const EAX30BUFFERPROPERTIES
*props
;
686 } data
= { pPropData
};
688 buf
->deferred
.eax
= *data
.props
;
689 ApplyFilterParams(buf
, data
.props
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
691 buf
->dirty
.bit
.dry_filter
= 1;
692 buf
->dirty
.bit
.wet_filter
= 1;
693 buf
->dirty
.bit
.room_rolloff
= 1;
694 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
695 buf
->dirty
.bit
.air_absorb
= 1;
696 buf
->dirty
.bit
.flags
= 1;
701 case DSPROPERTY_EAX30BUFFER_DIRECT
:
702 if(cbPropData
>= sizeof(LONG
))
704 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
706 buf
->deferred
.eax
.lDirect
= *data
.l
;
707 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
709 buf
->dirty
.bit
.dry_filter
= 1;
713 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
714 if(cbPropData
>= sizeof(LONG
))
716 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
718 buf
->deferred
.eax
.lDirectHF
= *data
.l
;
719 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
721 buf
->dirty
.bit
.dry_filter
= 1;
725 case DSPROPERTY_EAX30BUFFER_DIRECTLF
:
726 if(cbPropData
>= sizeof(LONG
))
728 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
730 buf
->deferred
.eax
.lDirectLF
= *data
.l
;
731 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
733 buf
->dirty
.bit
.dry_filter
= 1;
738 case DSPROPERTY_EAX30BUFFER_ROOM
:
739 if(cbPropData
>= sizeof(LONG
))
741 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
743 buf
->deferred
.eax
.lRoom
= *data
.l
;
744 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
746 buf
->dirty
.bit
.wet_filter
= 1;
750 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
751 if(cbPropData
>= sizeof(LONG
))
753 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
755 buf
->deferred
.eax
.lRoomHF
= *data
.l
;
756 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
758 buf
->dirty
.bit
.wet_filter
= 1;
762 case DSPROPERTY_EAX30BUFFER_ROOMLF
:
763 if(cbPropData
>= sizeof(LONG
))
765 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
767 buf
->deferred
.eax
.lRoomLF
= *data
.l
;
768 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
770 buf
->dirty
.bit
.wet_filter
= 1;
775 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
776 if(cbPropData
>= sizeof(FLOAT
))
778 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
780 buf
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
782 buf
->dirty
.bit
.room_rolloff
= 1;
787 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
788 if(cbPropData
>= sizeof(LONG
))
790 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
792 buf
->deferred
.eax
.lObstruction
= *data
.l
;
793 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
795 buf
->dirty
.bit
.dry_filter
= 1;
799 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
800 if(cbPropData
>= sizeof(FLOAT
))
802 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
804 buf
->deferred
.eax
.flObstructionLFRatio
= *data
.fl
;
805 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
807 buf
->dirty
.bit
.dry_filter
= 1;
812 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
813 if(cbPropData
>= sizeof(LONG
))
815 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
817 buf
->deferred
.eax
.lOcclusion
= *data
.l
;
818 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
820 buf
->dirty
.bit
.dry_filter
= 1;
821 buf
->dirty
.bit
.wet_filter
= 1;
825 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
826 if(cbPropData
>= sizeof(FLOAT
))
828 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
830 buf
->deferred
.eax
.flOcclusionLFRatio
= *data
.fl
;
831 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
833 buf
->dirty
.bit
.dry_filter
= 1;
834 buf
->dirty
.bit
.wet_filter
= 1;
838 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
839 if(cbPropData
>= sizeof(FLOAT
))
841 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
843 buf
->deferred
.eax
.flOcclusionRoomRatio
= *data
.fl
;
844 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
846 buf
->dirty
.bit
.wet_filter
= 1;
850 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
851 if(cbPropData
>= sizeof(FLOAT
))
853 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
855 buf
->deferred
.eax
.flOcclusionDirectRatio
= *data
.fl
;
856 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
858 buf
->dirty
.bit
.dry_filter
= 1;
863 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
864 if(cbPropData
>= sizeof(LONG
))
866 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
868 buf
->deferred
.eax
.lExclusion
= *data
.l
;
869 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
871 buf
->dirty
.bit
.wet_filter
= 1;
875 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
876 if(cbPropData
>= sizeof(FLOAT
))
878 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
880 buf
->deferred
.eax
.flExclusionLFRatio
= *data
.fl
;
881 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
883 buf
->dirty
.bit
.wet_filter
= 1;
888 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
889 if(cbPropData
>= sizeof(LONG
))
891 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
893 buf
->deferred
.eax
.lOutsideVolumeHF
= *data
.l
;
895 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
900 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
901 if(cbPropData
>= sizeof(FLOAT
))
903 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
905 buf
->deferred
.eax
.flAirAbsorptionFactor
= *data
.fl
;
907 buf
->dirty
.bit
.air_absorb
= 1;
912 case DSPROPERTY_EAX30BUFFER_FLAGS
:
913 if(cbPropData
>= sizeof(DWORD
))
915 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
917 buf
->deferred
.eax
.dwFlags
= *data
.dw
;
919 buf
->dirty
.bit
.flags
= 1;
925 hr
= E_PROP_ID_UNSUPPORTED
;
926 FIXME("Unhandled buffer propid: 0x%08lx\n", propid
);
933 HRESULT
EAX3Buffer_Get(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
937 if(buf
->filter
[0] == 0)
938 return E_PROP_ID_UNSUPPORTED
;
940 #define GET_PROP(src, T) do { \
941 if(cbPropData >= sizeof(T)) \
943 union { void *v; T *props; } data = { pPropData }; \
945 *pcbReturned = sizeof(T); \
949 hr
= DSERR_INVALIDPARAM
;
952 case DSPROPERTY_EAX30BUFFER_NONE
:
957 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS
:
958 GET_PROP(buf
->deferred
.eax
, EAX30BUFFERPROPERTIES
);
961 case DSPROPERTY_EAX30BUFFER_DIRECT
:
962 GET_PROP(buf
->deferred
.eax
.lDirect
, LONG
);
964 case DSPROPERTY_EAX30BUFFER_DIRECTHF
:
965 GET_PROP(buf
->deferred
.eax
.lDirectHF
, LONG
);
967 case DSPROPERTY_EAX30BUFFER_DIRECTLF
:
968 GET_PROP(buf
->deferred
.eax
.lDirectLF
, LONG
);
971 case DSPROPERTY_EAX30BUFFER_ROOM
:
972 GET_PROP(buf
->deferred
.eax
.lRoom
, LONG
);
974 case DSPROPERTY_EAX30BUFFER_ROOMHF
:
975 GET_PROP(buf
->deferred
.eax
.lRoomHF
, LONG
);
977 case DSPROPERTY_EAX30BUFFER_ROOMLF
:
978 GET_PROP(buf
->deferred
.eax
.lRoomLF
, LONG
);
981 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR
:
982 GET_PROP(buf
->deferred
.eax
.flRoomRolloffFactor
, FLOAT
);
985 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION
:
986 GET_PROP(buf
->deferred
.eax
.lObstruction
, LONG
);
988 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO
:
989 GET_PROP(buf
->deferred
.eax
.flObstructionLFRatio
, FLOAT
);
992 case DSPROPERTY_EAX30BUFFER_OCCLUSION
:
993 GET_PROP(buf
->deferred
.eax
.lOcclusion
, LONG
);
995 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO
:
996 GET_PROP(buf
->deferred
.eax
.flOcclusionLFRatio
, FLOAT
);
998 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO
:
999 GET_PROP(buf
->deferred
.eax
.flOcclusionRoomRatio
, FLOAT
);
1001 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO
:
1002 GET_PROP(buf
->deferred
.eax
.flOcclusionDirectRatio
, FLOAT
);
1005 case DSPROPERTY_EAX30BUFFER_EXCLUSION
:
1006 GET_PROP(buf
->deferred
.eax
.lExclusion
, LONG
);
1008 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO
:
1009 GET_PROP(buf
->deferred
.eax
.flExclusionLFRatio
, FLOAT
);
1012 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF
:
1013 GET_PROP(buf
->deferred
.eax
.lOutsideVolumeHF
, LONG
);
1016 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR
:
1017 GET_PROP(buf
->deferred
.eax
.flAirAbsorptionFactor
, FLOAT
);
1020 case DSPROPERTY_EAX30BUFFER_FLAGS
:
1021 GET_PROP(buf
->deferred
.eax
.dwFlags
, DWORD
);
1025 hr
= E_PROP_ID_UNSUPPORTED
;
1026 FIXME("Unhandled buffer propid: 0x%08lx\n", propid
);
1035 /*******************
1039 #define EAX2LISTENERFLAGS_MASK (EAX20LISTENERFLAGS_DECAYTIMESCALE | \
1040 EAX20LISTENERFLAGS_REFLECTIONSSCALE | \
1041 EAX20LISTENERFLAGS_REFLECTIONSDELAYSCALE | \
1042 EAX20LISTENERFLAGS_REVERBSCALE | \
1043 EAX20LISTENERFLAGS_REVERBDELAYSCALE | \
1044 EAX20LISTENERFLAGS_DECAYHFLIMIT)
1046 static EAX20LISTENERPROPERTIES
EAX3To2(const EAX30LISTENERPROPERTIES
*props
)
1048 EAX20LISTENERPROPERTIES ret
;
1049 ret
.lRoom
= props
->lRoom
;
1050 ret
.lRoomHF
= props
->lRoomHF
;
1051 ret
.flRoomRolloffFactor
= props
->flRoomRolloffFactor
;
1052 ret
.flDecayTime
= props
->flDecayTime
;
1053 ret
.flDecayHFRatio
= props
->flDecayHFRatio
;
1054 ret
.lReflections
= props
->lReflections
;
1055 ret
.flReflectionsDelay
= props
->flReflectionsDelay
;
1056 ret
.lReverb
= props
->lReverb
;
1057 ret
.flReverbDelay
= props
->flReverbDelay
;
1058 ret
.dwEnvironment
= props
->dwEnvironment
;
1059 ret
.flEnvironmentSize
= props
->flEnvironmentSize
;
1060 ret
.flEnvironmentDiffusion
= props
->flEnvironmentDiffusion
;
1061 ret
.flAirAbsorptionHF
= props
->flAirAbsorptionHF
;
1062 ret
.dwFlags
= props
->dwFlags
& EAX2LISTENERFLAGS_MASK
;
1066 static EAX20BUFFERPROPERTIES
EAXBuffer3To2(const EAX30BUFFERPROPERTIES
*props
)
1068 EAX20BUFFERPROPERTIES ret
;
1069 ret
.lDirect
= props
->lDirect
;
1070 ret
.lDirectHF
= props
->lDirectHF
;
1071 ret
.lRoom
= props
->lRoom
;
1072 ret
.lRoomHF
= props
->lRoomHF
;
1073 ret
.flRoomRolloffFactor
= props
->flRoomRolloffFactor
;
1074 ret
.lObstruction
= props
->lObstruction
;
1075 ret
.flObstructionLFRatio
= props
->flObstructionLFRatio
;
1076 ret
.lOcclusion
= props
->lOcclusion
;
1077 ret
.flOcclusionLFRatio
= props
->flOcclusionLFRatio
;
1078 ret
.flOcclusionRoomRatio
= props
->flOcclusionRoomRatio
;
1079 ret
.lOutsideVolumeHF
= props
->lOutsideVolumeHF
;
1080 ret
.flAirAbsorptionFactor
= props
->flAirAbsorptionFactor
;
1081 ret
.dwFlags
= props
->dwFlags
;
1086 HRESULT
EAX2_Set(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
1090 if(prim
->effect
== 0)
1091 return E_PROP_ID_UNSUPPORTED
;
1093 hr
= DSERR_INVALIDPARAM
;
1096 case DSPROPERTY_EAX20LISTENER_NONE
: /* not setting any property, just applying */
1100 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
1101 if(cbPropData
>= sizeof(EAX20LISTENERPROPERTIES
))
1105 const EAX20LISTENERPROPERTIES
*props
;
1106 } data
= { pPropData
};
1107 EAX30LISTENERPROPERTIES props3
= REVERB_PRESET_GENERIC
;
1108 if(data
.props
->dwEnvironment
< EAX_ENVIRONMENT_COUNT
)
1110 props3
= EnvironmentDefaults
[data
.props
->dwEnvironment
];
1111 props3
.dwEnvironment
= data
.props
->dwEnvironment
;
1113 props3
.flEnvironmentSize
= data
.props
->flEnvironmentSize
;
1114 props3
.flEnvironmentDiffusion
= data
.props
->flEnvironmentDiffusion
;
1115 props3
.lRoom
= data
.props
->lRoom
;
1116 props3
.lRoomHF
= data
.props
->lRoomHF
;
1117 props3
.flDecayTime
= data
.props
->flDecayTime
;
1118 props3
.flDecayHFRatio
= data
.props
->flDecayHFRatio
;
1119 props3
.lReflections
= data
.props
->lReflections
;
1120 props3
.flReflectionsDelay
= data
.props
->flReflectionsDelay
;
1121 props3
.lReverb
= data
.props
->lReverb
;
1122 props3
.flReverbDelay
= data
.props
->flReverbDelay
;
1123 props3
.flAirAbsorptionHF
= data
.props
->flAirAbsorptionHF
;
1124 props3
.flRoomRolloffFactor
= data
.props
->flRoomRolloffFactor
;
1125 props3
.dwFlags
= data
.props
->dwFlags
;
1127 ApplyReverbParams(prim
, &props3
);
1132 case DSPROPERTY_EAX20LISTENER_ROOM
:
1133 if(cbPropData
>= sizeof(LONG
))
1135 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1137 prim
->deferred
.eax
.lRoom
= *data
.l
;
1138 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
,
1139 mB_to_gain(prim
->deferred
.eax
.lRoom
));
1142 prim
->dirty
.bit
.effect
= 1;
1146 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
1147 if(cbPropData
>= sizeof(LONG
))
1149 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1151 prim
->deferred
.eax
.lRoomHF
= *data
.l
;
1152 alEffectf(prim
->effect
, AL_EAXREVERB_GAINHF
,
1153 mB_to_gain(prim
->deferred
.eax
.lRoomHF
));
1156 prim
->dirty
.bit
.effect
= 1;
1161 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
1162 if(cbPropData
>= sizeof(FLOAT
))
1164 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1166 prim
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
1167 alEffectf(prim
->effect
, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
,
1168 prim
->deferred
.eax
.flRoomRolloffFactor
);
1171 prim
->dirty
.bit
.effect
= 1;
1176 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
1177 if(cbPropData
>= sizeof(FLOAT
))
1179 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1181 prim
->deferred
.eax
.flDecayTime
= *data
.fl
;
1182 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
,
1183 prim
->deferred
.eax
.flDecayTime
);
1186 prim
->dirty
.bit
.effect
= 1;
1190 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
1191 if(cbPropData
>= sizeof(FLOAT
))
1193 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1195 prim
->deferred
.eax
.flDecayHFRatio
= *data
.fl
;
1196 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_HFRATIO
,
1197 prim
->deferred
.eax
.flDecayHFRatio
);
1200 prim
->dirty
.bit
.effect
= 1;
1205 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
1206 if(cbPropData
>= sizeof(LONG
))
1208 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1210 prim
->deferred
.eax
.lReflections
= *data
.l
;
1211 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_GAIN
,
1212 mB_to_gain(prim
->deferred
.eax
.lReflections
));
1215 prim
->dirty
.bit
.effect
= 1;
1219 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
1220 if(cbPropData
>= sizeof(FLOAT
))
1222 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1224 prim
->deferred
.eax
.flReflectionsDelay
= *data
.fl
;
1225 alEffectf(prim
->effect
, AL_EAXREVERB_REFLECTIONS_DELAY
,
1226 prim
->deferred
.eax
.flReflectionsDelay
);
1229 prim
->dirty
.bit
.effect
= 1;
1234 case DSPROPERTY_EAX20LISTENER_REVERB
:
1235 if(cbPropData
>= sizeof(LONG
))
1237 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1239 prim
->deferred
.eax
.lReverb
= *data
.l
;
1240 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_GAIN
,
1241 mB_to_gain(prim
->deferred
.eax
.lReverb
));
1244 prim
->dirty
.bit
.effect
= 1;
1248 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
1249 if(cbPropData
>= sizeof(FLOAT
))
1251 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1253 prim
->deferred
.eax
.flReverbDelay
= *data
.fl
;
1254 alEffectf(prim
->effect
, AL_EAXREVERB_LATE_REVERB_DELAY
,
1255 prim
->deferred
.eax
.flReverbDelay
);
1258 prim
->dirty
.bit
.effect
= 1;
1263 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
1264 if(cbPropData
>= sizeof(DWORD
))
1266 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1267 if(*data
.dw
< EAX_ENVIRONMENT_COUNT
)
1269 ApplyReverbParams(prim
, &EnvironmentDefaults
[*data
.dw
]);
1275 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
1276 if(cbPropData
>= sizeof(FLOAT
))
1278 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1279 if(*data
.fl
>= 1.0f
&& *data
.fl
<= 100.0f
)
1281 float scale
= (*data
.fl
)/prim
->deferred
.eax
.flEnvironmentSize
;
1283 prim
->deferred
.eax
.flEnvironmentSize
= *data
.fl
;
1285 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_DECAYTIMESCALE
))
1287 prim
->deferred
.eax
.flDecayTime
*= scale
;
1288 prim
->deferred
.eax
.flDecayTime
= clampF(prim
->deferred
.eax
.flDecayTime
, 0.1f
, 20.0f
);
1290 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSSCALE
))
1292 prim
->deferred
.eax
.lReflections
-= gain_to_mB(scale
);
1293 prim
->deferred
.eax
.lReflections
= clampI(prim
->deferred
.eax
.lReflections
, -10000, 1000);
1295 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REFLECTIONSDELAYSCALE
))
1297 prim
->deferred
.eax
.flReflectionsDelay
*= scale
;
1298 prim
->deferred
.eax
.flReflectionsDelay
= clampF(prim
->deferred
.eax
.flReflectionsDelay
, 0.0f
, 0.3f
);
1300 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REVERBSCALE
))
1302 prim
->deferred
.eax
.lReverb
-= gain_to_mB(scale
);
1303 prim
->deferred
.eax
.lReverb
= clampI(prim
->deferred
.eax
.lReverb
, -10000, 2000);
1305 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_REVERBDELAYSCALE
))
1307 prim
->deferred
.eax
.flReverbDelay
*= scale
;
1308 prim
->deferred
.eax
.flReverbDelay
= clampF(prim
->deferred
.eax
.flReverbDelay
, 0.0f
, 0.1f
);
1310 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_ECHOTIMESCALE
))
1312 prim
->deferred
.eax
.flEchoTime
*= scale
;
1313 prim
->deferred
.eax
.flEchoTime
= clampF(prim
->deferred
.eax
.flEchoTime
, 0.075f
, 0.25f
);
1315 if((prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_MODTIMESCALE
))
1317 prim
->deferred
.eax
.flModulationTime
*= scale
;
1318 prim
->deferred
.eax
.flModulationTime
= clampF(prim
->deferred
.eax
.flModulationTime
, 0.04f
, 4.0f
);
1321 ApplyReverbParams(prim
, &prim
->deferred
.eax
);
1326 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
1327 if(cbPropData
>= sizeof(FLOAT
))
1329 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1331 prim
->deferred
.eax
.flEnvironmentDiffusion
= *data
.fl
;
1332 alEffectf(prim
->effect
, AL_EAXREVERB_DIFFUSION
,
1333 prim
->deferred
.eax
.flEnvironmentDiffusion
);
1336 prim
->dirty
.bit
.effect
= 1;
1341 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
1342 if(cbPropData
>= sizeof(FLOAT
))
1344 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1346 prim
->deferred
.eax
.flAirAbsorptionHF
= *data
.fl
;
1347 alEffectf(prim
->effect
, AL_EAXREVERB_AIR_ABSORPTION_GAINHF
,
1348 mB_to_gain(prim
->deferred
.eax
.flAirAbsorptionHF
));
1351 prim
->dirty
.bit
.effect
= 1;
1356 case DSPROPERTY_EAX20LISTENER_FLAGS
:
1357 if(cbPropData
>= sizeof(DWORD
))
1359 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1361 prim
->deferred
.eax
.dwFlags
= *data
.dw
;
1362 alEffecti(prim
->effect
, AL_EAXREVERB_DECAY_HFLIMIT
,
1363 (prim
->deferred
.eax
.dwFlags
&EAX30LISTENERFLAGS_DECAYHFLIMIT
) ?
1364 AL_TRUE
: AL_FALSE
);
1367 prim
->dirty
.bit
.effect
= 1;
1373 hr
= E_PROP_ID_UNSUPPORTED
;
1374 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
1381 HRESULT
EAX2_Get(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
1385 if(prim
->effect
== 0)
1386 return E_PROP_ID_UNSUPPORTED
;
1388 #define GET_PROP(src, T) do { \
1389 if(cbPropData >= sizeof(T)) \
1391 union { void *v; T *props; } data = { pPropData }; \
1392 *data.props = src; \
1393 *pcbReturned = sizeof(T); \
1397 hr
= DSERR_INVALIDPARAM
;
1400 case DSPROPERTY_EAX20LISTENER_NONE
:
1405 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
:
1406 GET_PROP(EAX3To2(&prim
->deferred
.eax
), EAX20LISTENERPROPERTIES
);
1409 case DSPROPERTY_EAX20LISTENER_ROOM
:
1410 GET_PROP(prim
->deferred
.eax
.lRoom
, LONG
);
1412 case DSPROPERTY_EAX20LISTENER_ROOMHF
:
1413 GET_PROP(prim
->deferred
.eax
.lRoomHF
, LONG
);
1416 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR
:
1417 GET_PROP(prim
->deferred
.eax
.flRoomRolloffFactor
, FLOAT
);
1420 case DSPROPERTY_EAX20LISTENER_DECAYTIME
:
1421 GET_PROP(prim
->deferred
.eax
.flDecayTime
, FLOAT
);
1423 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO
:
1424 GET_PROP(prim
->deferred
.eax
.flDecayHFRatio
, FLOAT
);
1427 case DSPROPERTY_EAX20LISTENER_REFLECTIONS
:
1428 GET_PROP(prim
->deferred
.eax
.lReflections
, LONG
);
1430 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY
:
1431 GET_PROP(prim
->deferred
.eax
.flReflectionsDelay
, FLOAT
);
1434 case DSPROPERTY_EAX20LISTENER_REVERB
:
1435 GET_PROP(prim
->deferred
.eax
.lReverb
, LONG
);
1437 case DSPROPERTY_EAX20LISTENER_REVERBDELAY
:
1438 GET_PROP(prim
->deferred
.eax
.flReverbDelay
, FLOAT
);
1441 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT
:
1442 GET_PROP(prim
->deferred
.eax
.dwEnvironment
, DWORD
);
1445 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE
:
1446 GET_PROP(prim
->deferred
.eax
.flEnvironmentSize
, FLOAT
);
1448 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION
:
1449 GET_PROP(prim
->deferred
.eax
.flEnvironmentDiffusion
, FLOAT
);
1452 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF
:
1453 GET_PROP(prim
->deferred
.eax
.flAirAbsorptionHF
, FLOAT
);
1456 case DSPROPERTY_EAX20LISTENER_FLAGS
:
1457 GET_PROP(prim
->deferred
.eax
.dwFlags
&EAX2LISTENERFLAGS_MASK
, DWORD
);
1461 hr
= E_PROP_ID_UNSUPPORTED
;
1462 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
1471 HRESULT
EAX2Buffer_Set(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
1475 if(buf
->filter
[0] == 0)
1476 return E_PROP_ID_UNSUPPORTED
;
1478 hr
= DSERR_INVALIDPARAM
;
1481 case DSPROPERTY_EAX20BUFFER_NONE
: /* not setting any property, just applying */
1485 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
1486 if(cbPropData
>= sizeof(EAX20BUFFERPROPERTIES
))
1490 const EAX20BUFFERPROPERTIES
*props
;
1491 } data
= { pPropData
};
1493 buf
->deferred
.eax
.lDirect
= data
.props
->lDirect
;
1494 buf
->deferred
.eax
.lDirectHF
= data
.props
->lDirectHF
;
1495 buf
->deferred
.eax
.lRoom
= data
.props
->lRoom
;
1496 buf
->deferred
.eax
.lRoomHF
= data
.props
->lRoomHF
;
1497 buf
->deferred
.eax
.flRoomRolloffFactor
= data
.props
->flRoomRolloffFactor
;
1498 buf
->deferred
.eax
.lObstruction
= data
.props
->lObstruction
;
1499 buf
->deferred
.eax
.flObstructionLFRatio
= data
.props
->flObstructionLFRatio
;
1500 buf
->deferred
.eax
.lOcclusion
= data
.props
->lOcclusion
;
1501 buf
->deferred
.eax
.flOcclusionLFRatio
= data
.props
->flOcclusionLFRatio
;
1502 buf
->deferred
.eax
.flOcclusionRoomRatio
= data
.props
->flOcclusionRoomRatio
;
1503 buf
->deferred
.eax
.lOutsideVolumeHF
= data
.props
->lOutsideVolumeHF
;
1504 buf
->deferred
.eax
.flAirAbsorptionFactor
= data
.props
->flAirAbsorptionFactor
;
1505 buf
->deferred
.eax
.dwFlags
= data
.props
->dwFlags
;
1506 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1508 buf
->dirty
.bit
.dry_filter
= 1;
1509 buf
->dirty
.bit
.wet_filter
= 1;
1510 buf
->dirty
.bit
.room_rolloff
= 1;
1511 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
1512 buf
->dirty
.bit
.air_absorb
= 1;
1513 buf
->dirty
.bit
.flags
= 1;
1518 case DSPROPERTY_EAX20BUFFER_DIRECT
:
1519 if(cbPropData
>= sizeof(LONG
))
1521 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1523 buf
->deferred
.eax
.lDirect
= *data
.l
;
1524 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1526 buf
->dirty
.bit
.dry_filter
= 1;
1530 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
1531 if(cbPropData
>= sizeof(LONG
))
1533 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1535 buf
->deferred
.eax
.lDirectHF
= *data
.l
;
1536 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1538 buf
->dirty
.bit
.dry_filter
= 1;
1543 case DSPROPERTY_EAX20BUFFER_ROOM
:
1544 if(cbPropData
>= sizeof(LONG
))
1546 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1548 buf
->deferred
.eax
.lRoom
= *data
.l
;
1549 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1551 buf
->dirty
.bit
.wet_filter
= 1;
1555 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
1556 if(cbPropData
>= sizeof(LONG
))
1558 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1560 buf
->deferred
.eax
.lRoomHF
= *data
.l
;
1561 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
1563 buf
->dirty
.bit
.wet_filter
= 1;
1568 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
1569 if(cbPropData
>= sizeof(FLOAT
))
1571 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1573 buf
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
1575 buf
->dirty
.bit
.room_rolloff
= 1;
1580 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
1581 if(cbPropData
>= sizeof(LONG
))
1583 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1585 buf
->deferred
.eax
.lObstruction
= *data
.l
;
1586 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1588 buf
->dirty
.bit
.dry_filter
= 1;
1592 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
1593 if(cbPropData
>= sizeof(FLOAT
))
1595 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1597 buf
->deferred
.eax
.flObstructionLFRatio
= *data
.fl
;
1598 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
1600 buf
->dirty
.bit
.dry_filter
= 1;
1605 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
1606 if(cbPropData
>= sizeof(LONG
))
1608 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1610 buf
->deferred
.eax
.lOcclusion
= *data
.l
;
1611 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1613 buf
->dirty
.bit
.dry_filter
= 1;
1614 buf
->dirty
.bit
.wet_filter
= 1;
1618 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
1619 if(cbPropData
>= sizeof(FLOAT
))
1621 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1623 buf
->deferred
.eax
.flOcclusionLFRatio
= *data
.fl
;
1624 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1626 buf
->dirty
.bit
.dry_filter
= 1;
1627 buf
->dirty
.bit
.wet_filter
= 1;
1631 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
1632 if(cbPropData
>= sizeof(FLOAT
))
1634 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1636 buf
->deferred
.eax
.flOcclusionRoomRatio
= *data
.fl
;
1637 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
|APPLY_WET_PARAMS
);
1639 buf
->dirty
.bit
.dry_filter
= 1;
1640 buf
->dirty
.bit
.wet_filter
= 1;
1645 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
1646 if(cbPropData
>= sizeof(LONG
))
1648 union { const void *v
; const LONG
*l
; } data
= { pPropData
};
1650 buf
->deferred
.eax
.lOutsideVolumeHF
= *data
.l
;
1652 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
1657 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
1658 if(cbPropData
>= sizeof(FLOAT
))
1660 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1662 buf
->deferred
.eax
.flAirAbsorptionFactor
= *data
.fl
;
1664 buf
->dirty
.bit
.air_absorb
= 1;
1669 case DSPROPERTY_EAX20BUFFER_FLAGS
:
1670 if(cbPropData
>= sizeof(DWORD
))
1672 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1674 buf
->deferred
.eax
.dwFlags
= *data
.dw
;
1676 buf
->dirty
.bit
.flags
= 1;
1682 hr
= E_PROP_ID_UNSUPPORTED
;
1683 FIXME("Unhandled buffer propid: 0x%08lx\n", propid
);
1690 HRESULT
EAX2Buffer_Get(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
1694 if(buf
->filter
[0] == 0)
1695 return E_PROP_ID_UNSUPPORTED
;
1697 #define GET_PROP(src, T) do { \
1698 if(cbPropData >= sizeof(T)) \
1700 union { void *v; T *props; } data = { pPropData }; \
1701 *data.props = src; \
1702 *pcbReturned = sizeof(T); \
1706 hr
= DSERR_INVALIDPARAM
;
1709 case DSPROPERTY_EAX20BUFFER_NONE
:
1714 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
:
1715 GET_PROP(EAXBuffer3To2(&buf
->deferred
.eax
), EAX20BUFFERPROPERTIES
);
1718 case DSPROPERTY_EAX20BUFFER_DIRECT
:
1719 GET_PROP(buf
->deferred
.eax
.lDirect
, LONG
);
1721 case DSPROPERTY_EAX20BUFFER_DIRECTHF
:
1722 GET_PROP(buf
->deferred
.eax
.lDirectHF
, LONG
);
1725 case DSPROPERTY_EAX20BUFFER_ROOM
:
1726 GET_PROP(buf
->deferred
.eax
.lRoom
, LONG
);
1728 case DSPROPERTY_EAX20BUFFER_ROOMHF
:
1729 GET_PROP(buf
->deferred
.eax
.lRoomHF
, LONG
);
1732 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR
:
1733 GET_PROP(buf
->deferred
.eax
.flRoomRolloffFactor
, FLOAT
);
1736 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION
:
1737 GET_PROP(buf
->deferred
.eax
.lObstruction
, LONG
);
1739 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO
:
1740 GET_PROP(buf
->deferred
.eax
.flObstructionLFRatio
, FLOAT
);
1743 case DSPROPERTY_EAX20BUFFER_OCCLUSION
:
1744 GET_PROP(buf
->deferred
.eax
.lOcclusion
, LONG
);
1746 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO
:
1747 GET_PROP(buf
->deferred
.eax
.flOcclusionLFRatio
, FLOAT
);
1749 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO
:
1750 GET_PROP(buf
->deferred
.eax
.flOcclusionRoomRatio
, FLOAT
);
1753 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF
:
1754 GET_PROP(buf
->deferred
.eax
.lOutsideVolumeHF
, LONG
);
1757 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR
:
1758 GET_PROP(buf
->deferred
.eax
.flAirAbsorptionFactor
, FLOAT
);
1761 case DSPROPERTY_EAX20BUFFER_FLAGS
:
1762 GET_PROP(buf
->deferred
.eax
.dwFlags
, DWORD
);
1766 hr
= E_PROP_ID_UNSUPPORTED
;
1767 FIXME("Unhandled buffer propid: 0x%08lx\n", propid
);
1776 /*******************
1780 HRESULT
EAX1_Set(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
1782 static const float eax1_env_volume
[EAX_ENVIRONMENT_COUNT
] = {
1783 0.5f
, 0.25f
, 0.417f
, 0.653f
, 0.208f
, 0.5f
, 0.403f
, 0.5f
, 0.5f
,
1784 0.361f
, 0.5f
, 0.153f
, 0.361f
, 0.444f
, 0.25f
, 0.111f
, 0.111f
,
1785 0.194f
, 1.0f
, 0.097f
, 0.208f
, 0.652f
, 1.0f
, 0.875f
, 0.139f
, 0.486f
1787 static const float eax1_env_dampening
[EAX_ENVIRONMENT_COUNT
] = {
1788 0.5f
, 0.0f
, 0.666f
, 0.166f
, 0.0f
, 0.888f
, 0.5f
, 0.5f
, 1.304f
,
1789 0.332f
, 0.3f
, 2.0f
, 0.0f
, 0.638f
, 0.776f
, 0.472f
, 0.224f
, 0.472f
,
1790 0.5f
, 0.224f
, 1.5f
, 0.25f
, 0.0f
, 1.388f
, 0.666f
, 0.806f
1794 if(prim
->effect
== 0)
1795 return E_PROP_ID_UNSUPPORTED
;
1797 hr
= DSERR_INVALIDPARAM
;
1800 case DSPROPERTY_EAX1_ALL
:
1801 if(cbPropData
>= sizeof(EAX1_REVERBPROPERTIES
))
1805 const EAX1_REVERBPROPERTIES
*props
;
1806 } data
= { pPropData
};
1808 if(data
.props
->dwEnvironment
< EAX_ENVIRONMENT_COUNT
)
1810 /* NOTE: I'm not quite sure how to handle the volume. It's
1811 * important to deal with since it can have a notable impact on
1812 * the output levels, but given the default EAX1 environment
1813 * volumes, they don't align with the gain/room volume for
1814 * EAX2+ environments. Presuming the default volumes are
1815 * correct, it's possible the reverb implementation was
1816 * different and relied on different gains to get the intended
1819 * Rather than just blindly applying the volume, we take the
1820 * difference from the EAX1 environment's default volume and
1821 * apply that as an offset to the EAX2 environment's volume.
1823 EAX30LISTENERPROPERTIES env
= EnvironmentDefaults
[data
.props
->dwEnvironment
];
1824 LONG db_vol
= clampI(
1825 gain_to_mB(data
.props
->fVolume
/ eax1_env_volume
[data
.props
->dwEnvironment
]),
1828 env
.lRoom
= clampI(env
.lRoom
+ db_vol
, -10000, 0);
1829 env
.flDecayTime
= data
.props
->fDecayTime
;
1830 prim
->deferred
.eax1_volume
= data
.props
->fVolume
;
1831 prim
->deferred
.eax1_dampening
= data
.props
->fDamping
;
1832 ApplyReverbParams(prim
, &env
);
1838 case DSPROPERTY_EAX1_ENVIRONMENT
:
1839 if(cbPropData
>= sizeof(DWORD
))
1841 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1843 if(*data
.dw
< EAX_ENVIRONMENT_COUNT
)
1845 prim
->deferred
.eax1_volume
= eax1_env_volume
[*data
.dw
];
1846 prim
->deferred
.eax1_dampening
= eax1_env_dampening
[*data
.dw
];
1847 ApplyReverbParams(prim
, &EnvironmentDefaults
[*data
.dw
]);
1853 case DSPROPERTY_EAX1_VOLUME
:
1854 if(cbPropData
>= sizeof(FLOAT
))
1856 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1857 LONG db_vol
= clampI(
1858 gain_to_mB(*data
.fl
/ eax1_env_volume
[prim
->deferred
.eax
.dwEnvironment
]),
1861 LONG room_vol
= clampI(
1862 EnvironmentDefaults
[prim
->deferred
.eax
.dwEnvironment
].lRoom
+ db_vol
,
1866 prim
->deferred
.eax
.lRoom
= room_vol
;
1867 prim
->deferred
.eax1_volume
= *data
.fl
;
1868 alEffectf(prim
->effect
, AL_EAXREVERB_GAIN
, mB_to_gain(room_vol
));
1871 prim
->dirty
.bit
.effect
= 1;
1875 case DSPROPERTY_EAX1_DECAYTIME
:
1876 if(cbPropData
>= sizeof(FLOAT
))
1878 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1880 prim
->deferred
.eax
.flDecayTime
= *data
.fl
;
1881 alEffectf(prim
->effect
, AL_EAXREVERB_DECAY_TIME
,
1882 prim
->deferred
.eax
.flDecayTime
);
1885 prim
->dirty
.bit
.effect
= 1;
1889 case DSPROPERTY_EAX1_DAMPING
:
1890 if(cbPropData
>= sizeof(FLOAT
))
1892 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
1894 prim
->deferred
.eax1_dampening
= *data
.fl
;
1901 hr
= E_PROP_ID_UNSUPPORTED
;
1902 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
1909 HRESULT
EAX1_Get(DS8Primary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
1913 if(prim
->effect
== 0)
1914 return E_PROP_ID_UNSUPPORTED
;
1916 hr
= DSERR_INVALIDPARAM
;
1919 case DSPROPERTY_EAX1_ALL
:
1920 if(cbPropData
>= sizeof(EAX1_REVERBPROPERTIES
))
1924 EAX1_REVERBPROPERTIES
*props
;
1925 } data
= { pPropData
};
1927 data
.props
->dwEnvironment
= prim
->deferred
.eax
.dwEnvironment
;
1928 data
.props
->fVolume
= prim
->deferred
.eax1_volume
;
1929 data
.props
->fDecayTime
= prim
->deferred
.eax
.flDecayTime
;
1930 data
.props
->fDamping
= prim
->deferred
.eax1_dampening
;
1932 *pcbReturned
= sizeof(EAX1_REVERBPROPERTIES
);
1937 case DSPROPERTY_EAX1_ENVIRONMENT
:
1938 if(cbPropData
>= sizeof(DWORD
))
1940 union { void *v
; DWORD
*dw
; } data
= { pPropData
};
1942 *data
.dw
= prim
->deferred
.eax
.dwEnvironment
;
1944 *pcbReturned
= sizeof(DWORD
);
1949 case DSPROPERTY_EAX1_VOLUME
:
1950 if(cbPropData
>= sizeof(FLOAT
))
1952 union { void *v
; FLOAT
*fl
; } data
= { pPropData
};
1954 *data
.fl
= prim
->deferred
.eax1_volume
;
1956 *pcbReturned
= sizeof(FLOAT
);
1961 case DSPROPERTY_EAX1_DECAYTIME
:
1962 if(cbPropData
>= sizeof(FLOAT
))
1964 union { void *v
; FLOAT
*fl
; } data
= { pPropData
};
1966 *data
.fl
= prim
->deferred
.eax
.flDecayTime
;
1968 *pcbReturned
= sizeof(FLOAT
);
1973 case DSPROPERTY_EAX1_DAMPING
:
1974 if(cbPropData
>= sizeof(FLOAT
))
1976 union { void *v
; FLOAT
*fl
; } data
= { pPropData
};
1978 *data
.fl
= prim
->deferred
.eax1_dampening
;
1980 *pcbReturned
= sizeof(FLOAT
);
1986 hr
= E_PROP_ID_UNSUPPORTED
;
1987 FIXME("Unhandled listener propid: 0x%08lx\n", propid
);
1994 HRESULT
EAX1Buffer_Set(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
1998 if(buf
->filter
[0] == 0)
1999 return E_PROP_ID_UNSUPPORTED
;
2001 hr
= DSERR_INVALIDPARAM
;
2004 /* NOTE: DSPROPERTY_EAX1BUFFER_ALL is for EAX1BUFFER_REVERBPROPERTIES,
2005 * however that struct just contains the single ReverbMix float property.
2007 case DSPROPERTY_EAX1BUFFER_ALL
:
2008 case DSPROPERTY_EAX1BUFFER_REVERBMIX
:
2009 if(cbPropData
>= sizeof(FLOAT
))
2011 union { const void *v
; const FLOAT
*fl
; } data
= { pPropData
};
2013 buf
->deferred
.eax
.lRoom
= gain_to_mB(*data
.fl
);
2014 buf
->deferred
.eax1_reverbmix
= *data
.fl
;
2015 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_WET_PARAMS
);
2017 buf
->dirty
.bit
.wet_filter
= 1;
2023 hr
= E_PROP_ID_UNSUPPORTED
;
2024 FIXME("Unhandled buffer propid: 0x%08lx\n", propid
);
2031 HRESULT
EAX1Buffer_Get(DS8Buffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
2035 if(buf
->filter
[0] == 0)
2036 return E_PROP_ID_UNSUPPORTED
;
2038 hr
= DSERR_INVALIDPARAM
;
2041 case DSPROPERTY_EAX1BUFFER_ALL
:
2042 case DSPROPERTY_EAX1BUFFER_REVERBMIX
:
2043 if(cbPropData
>= sizeof(FLOAT
))
2045 union { void *v
; FLOAT
*fl
; } data
= { pPropData
};
2047 *data
.fl
= buf
->deferred
.eax1_reverbmix
;
2048 *pcbReturned
= sizeof(FLOAT
);
2054 hr
= E_PROP_ID_UNSUPPORTED
;
2055 FIXME("Unhandled buffer propid: 0x%08lx\n", propid
);