Add missing file
[dsound-openal.git] / chorus.c
blobb16f88a5eef6190869034c41102a966bcb124be3
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
18 #define CONST_VTABLE
19 #include <stdarg.h>
20 #include <string.h>
22 #include "windows.h"
23 #include "dsound.h"
25 #include "dsound_private.h"
26 #include "eax4.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);
38 checkALError();
42 HRESULT EAXChorus_Set(DSPrimary *prim, LONG idx, DWORD propid, void *pPropData, ULONG cbPropData)
44 switch(propid)
46 case EAXCHORUS_NONE: /* not setting any property, just applying */
47 return DS_OK;
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);
95 return DS_OK;
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);
113 checkALError();
115 FXSLOT_SET_DIRTY(prim->dirty.bit, idx, FXSLOT_EFFECT_BIT);
116 return DS_OK;
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);
134 checkALError();
136 FXSLOT_SET_DIRTY(prim->dirty.bit, idx, FXSLOT_EFFECT_BIT);
137 return DS_OK;
139 return DSERR_INVALIDPARAM;
141 case EAXCHORUS_RATE:
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);
155 checkALError();
157 FXSLOT_SET_DIRTY(prim->dirty.bit, idx, FXSLOT_EFFECT_BIT);
158 return DS_OK;
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);
176 checkALError();
178 FXSLOT_SET_DIRTY(prim->dirty.bit, idx, FXSLOT_EFFECT_BIT);
179 return DS_OK;
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);
197 checkALError();
199 FXSLOT_SET_DIRTY(prim->dirty.bit, idx, FXSLOT_EFFECT_BIT);
200 return DS_OK;
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);
218 checkALError();
220 FXSLOT_SET_DIRTY(prim->dirty.bit, idx, FXSLOT_EFFECT_BIT);
221 return DS_OK;
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 }; \
233 *data.props = src; \
234 *pcbReturned = sizeof(T); \
235 return DS_OK; \
237 return DSERR_INVALIDPARAM; \
238 } while(0)
240 HRESULT EAXChorus_Get(DSPrimary *prim, DWORD idx, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
242 switch(propid)
244 case EAXCHORUS_NONE:
245 *pcbReturned = 0;
246 return DS_OK;
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);
255 case EAXCHORUS_RATE:
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;