1 /* EAX chorus 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"
29 static void ApplyChorusParams(ALuint effect
, const EAXCHORUSPROPERTIES
*props
)
31 alEffecti(effect
, AL_CHORUS_WAVEFORM
, props
->dwWaveform
);
32 alEffecti(effect
, AL_CHORUS_PHASE
, props
->lPhase
);
33 alEffectf(effect
, AL_CHORUS_RATE
, props
->flRate
);
34 alEffectf(effect
, AL_CHORUS_DEPTH
, props
->flDepth
);
35 alEffectf(effect
, AL_CHORUS_FEEDBACK
, props
->flFeedback
);
36 alEffectf(effect
, AL_CHORUS_DELAY
, props
->flDelay
);
42 HRESULT
EAXChorus_Set(DSPrimary
*prim
, LONG idx
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
46 case EAXCHORUS_NONE
: /* not setting any property, just applying */
49 case EAXCHORUS_ALLPARAMETERS
:
50 if(cbPropData
>= sizeof(EAXCHORUSPROPERTIES
))
52 union { const void *v
; const EAXCHORUSPROPERTIES
*props
; } data
= { pPropData
};
53 TRACE("Parameters:\n\tWaveform: %lu\n\tPhase: %ld\n\tRate: %f\n\t"
54 "Depth: %f\n\tFeedback: %f\n\tDelay: %f\n",
55 data
.props
->dwWaveform
, data
.props
->lPhase
, data
.props
->flRate
,
56 data
.props
->flDepth
, data
.props
->flFeedback
, data
.props
->flDelay
59 if(data
.props
->dwWaveform
!= EAX_CHORUS_SINUSOID
&&
60 data
.props
->dwWaveform
!= EAX_CHORUS_TRIANGLE
)
62 ERR("Unexpected chorus waveform: %lu\n", data
.props
->dwWaveform
);
63 return DSERR_INVALIDPARAM
;
65 if(data
.props
->lPhase
< -180 || data
.props
->lPhase
> 180)
67 ERR("Unexpected chorus phase: %ld\n", data
.props
->lPhase
);
68 return DSERR_INVALIDPARAM
;
70 if(data
.props
->flRate
< 0.0f
|| data
.props
->flRate
> 10.0f
)
72 ERR("Unexpected chorus rate: %f\n", data
.props
->flRate
);
73 return DSERR_INVALIDPARAM
;
75 if(data
.props
->flDepth
< 0.0f
|| data
.props
->flDepth
> 1.0f
)
77 ERR("Unexpected chorus depth: %f\n", data
.props
->flDepth
);
78 return DSERR_INVALIDPARAM
;
80 if(data
.props
->flFeedback
< -1.0f
|| data
.props
->flFeedback
> 1.0f
)
82 ERR("Unexpected chorus feedback: %f\n", data
.props
->flFeedback
);
83 return DSERR_INVALIDPARAM
;
85 if(data
.props
->flDelay
< 0.0f
|| data
.props
->flDelay
> 0.016f
)
87 ERR("Unexpected chorus delay: %f\n", data
.props
->flDelay
);
88 return DSERR_INVALIDPARAM
;
91 prim
->deferred
.fxslot
[idx
].fx
.chorus
= *data
.props
;
92 ApplyChorusParams(prim
->effect
[idx
], data
.props
);
94 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
97 return DSERR_INVALIDPARAM
;
99 case EAXCHORUS_WAVEFORM
:
100 if(cbPropData
>= sizeof(DWORD
))
102 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
103 TRACE("Waveform: %lu\n", *data
.dw
);
105 if(*data
.dw
!= EAX_CHORUS_SINUSOID
&& *data
.dw
!= EAX_CHORUS_TRIANGLE
)
107 ERR("Unexpected chorus waveform: %lu\n", *data
.dw
);
108 return DSERR_INVALIDPARAM
;
111 prim
->deferred
.fxslot
[idx
].fx
.chorus
.dwWaveform
= *data
.dw
;
112 alEffecti(prim
->effect
[idx
], AL_CHORUS_WAVEFORM
, *data
.dw
);
115 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
118 return DSERR_INVALIDPARAM
;
120 case EAXCHORUS_PHASE
:
121 if(cbPropData
>= sizeof(long))
123 union { const void *v
; const long *l
; } data
= { pPropData
};
124 TRACE("Phase: %ld\n", *data
.l
);
126 if(*data
.l
< -180 || *data
.l
> 180)
128 ERR("Unexpected chorus phase: %ld\n", *data
.l
);
129 return DSERR_INVALIDPARAM
;
132 prim
->deferred
.fxslot
[idx
].fx
.chorus
.lPhase
= *data
.l
;
133 alEffecti(prim
->effect
[idx
], AL_CHORUS_PHASE
, *data
.l
);
136 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
139 return DSERR_INVALIDPARAM
;
142 if(cbPropData
>= sizeof(float))
144 union { const void *v
; const float *fl
; } data
= { pPropData
};
145 TRACE("Rate: %f\n", *data
.fl
);
147 if(*data
.fl
< 0.0f
|| *data
.fl
> 10.0f
)
149 ERR("Unexpected chorus rate: %f\n", *data
.fl
);
150 return DSERR_INVALIDPARAM
;
153 prim
->deferred
.fxslot
[idx
].fx
.chorus
.flRate
= *data
.fl
;
154 alEffectf(prim
->effect
[idx
], AL_CHORUS_RATE
, *data
.fl
);
157 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
160 return DSERR_INVALIDPARAM
;
162 case EAXCHORUS_DEPTH
:
163 if(cbPropData
>= sizeof(float))
165 union { const void *v
; const float *fl
; } data
= { pPropData
};
166 TRACE("Depth: %f\n", *data
.fl
);
168 if(*data
.fl
< 0.0f
|| *data
.fl
> 1.0f
)
170 ERR("Unexpected chorus depth: %f\n", *data
.fl
);
171 return DSERR_INVALIDPARAM
;
174 prim
->deferred
.fxslot
[idx
].fx
.chorus
.flDepth
= *data
.fl
;
175 alEffectf(prim
->effect
[idx
], AL_CHORUS_DEPTH
, *data
.fl
);
178 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
181 return DSERR_INVALIDPARAM
;
183 case EAXCHORUS_FEEDBACK
:
184 if(cbPropData
>= sizeof(float))
186 union { const void *v
; const float *fl
; } data
= { pPropData
};
187 TRACE("Feedback: %f\n", *data
.fl
);
189 if(*data
.fl
< -1.0f
|| *data
.fl
> 1.0f
)
191 ERR("Unexpected chorus feedback: %f\n", *data
.fl
);
192 return DSERR_INVALIDPARAM
;
195 prim
->deferred
.fxslot
[idx
].fx
.chorus
.flFeedback
= *data
.fl
;
196 alEffectf(prim
->effect
[idx
], AL_CHORUS_FEEDBACK
, *data
.fl
);
199 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
202 return DSERR_INVALIDPARAM
;
204 case EAXCHORUS_DELAY
:
205 if(cbPropData
>= sizeof(float))
207 union { const void *v
; const float *fl
; } data
= { pPropData
};
208 TRACE("Delay: %f\n", *data
.fl
);
210 if(*data
.fl
< 0.0f
|| *data
.fl
> 0.016f
)
212 ERR("Unexpected chorus delay: %f\n", *data
.fl
);
213 return DSERR_INVALIDPARAM
;
216 prim
->deferred
.fxslot
[idx
].fx
.chorus
.flDelay
= *data
.fl
;
217 alEffectf(prim
->effect
[idx
], AL_CHORUS_DELAY
, *data
.fl
);
220 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
223 return DSERR_INVALIDPARAM
;
225 FIXME("Unhandled propid: 0x%08lx\n", propid
);
226 return E_PROP_ID_UNSUPPORTED
;
229 #define GET_PROP(src, T) do { \
230 if(cbPropData >= sizeof(T)) \
232 union { void *v; T *props; } data = { pPropData }; \
234 *pcbReturned = sizeof(T); \
237 return DSERR_INVALIDPARAM; \
240 HRESULT
EAXChorus_Get(DSPrimary
*prim
, DWORD idx
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
248 case EAXCHORUS_ALLPARAMETERS
:
249 GET_PROP(prim
->current
.fxslot
[idx
].fx
.chorus
, EAXCHORUSPROPERTIES
);
251 case EAXCHORUS_WAVEFORM
:
252 GET_PROP(prim
->deferred
.fxslot
[idx
].fx
.chorus
.dwWaveform
, DWORD
);
253 case EAXCHORUS_PHASE
:
254 GET_PROP(prim
->deferred
.fxslot
[idx
].fx
.chorus
.lPhase
, long);
256 GET_PROP(prim
->deferred
.fxslot
[idx
].fx
.chorus
.flRate
, float);
257 case EAXCHORUS_DEPTH
:
258 GET_PROP(prim
->deferred
.fxslot
[idx
].fx
.chorus
.flDepth
, float);
259 case EAXCHORUS_FEEDBACK
:
260 GET_PROP(prim
->deferred
.fxslot
[idx
].fx
.chorus
.flFeedback
, float);
261 case EAXCHORUS_DELAY
:
262 GET_PROP(prim
->deferred
.fxslot
[idx
].fx
.chorus
.flDelay
, float);
264 FIXME("Unhandled propid: 0x%08lx\n", propid
);
265 return E_PROP_ID_UNSUPPORTED
;