Add filter properties
[openal-soft.git] / OpenAL32 / alFontsound.c
blobd5aebb74613dcf365ce725b5c707aa76aa28719f
2 #include "config.h"
4 #include <stdlib.h>
5 #include <string.h>
7 #include "alMain.h"
8 #include "alMidi.h"
9 #include "alError.h"
10 #include "alThunk.h"
12 #include "midi/base.h"
15 extern inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id);
16 extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id);
19 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids)
21 ALCdevice *device;
22 ALCcontext *context;
23 ALsizei cur = 0;
24 ALenum err;
26 context = GetContextRef();
27 if(!context) return;
29 if(!(n >= 0))
30 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
32 device = context->Device;
33 for(cur = 0;cur < n;cur++)
35 ALfontsound *inst = calloc(1, sizeof(ALfontsound));
36 if(!inst)
38 alDeleteFontsoundsSOFT(cur, ids);
39 SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
41 ALfontsound_Construct(inst);
43 err = NewThunkEntry(&inst->id);
44 if(err == AL_NO_ERROR)
45 err = InsertUIntMapEntry(&device->FontsoundMap, inst->id, inst);
46 if(err != AL_NO_ERROR)
48 ALfontsound_Destruct(inst);
49 memset(inst, 0, sizeof(*inst));
50 free(inst);
52 alDeleteFontsoundsSOFT(cur, ids);
53 SET_ERROR_AND_GOTO(context, err, done);
56 ids[cur] = inst->id;
59 done:
60 ALCcontext_DecRef(context);
63 AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids)
65 ALCdevice *device;
66 ALCcontext *context;
67 ALfontsound *inst;
68 ALsizei i;
70 context = GetContextRef();
71 if(!context) return;
73 if(!(n >= 0))
74 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
76 device = context->Device;
77 for(i = 0;i < n;i++)
79 /* Check for valid ID */
80 if((inst=LookupFontsound(device, ids[i])) == NULL)
81 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
82 if(inst->ref != 0)
83 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
86 for(i = 0;i < n;i++)
88 if((inst=RemoveFontsound(device, ids[i])) == NULL)
89 continue;
91 ALfontsound_Destruct(inst);
93 memset(inst, 0, sizeof(*inst));
94 free(inst);
97 done:
98 ALCcontext_DecRef(context);
101 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id)
103 ALCcontext *context;
104 ALboolean ret;
106 context = GetContextRef();
107 if(!context) return AL_FALSE;
109 ret = LookupFontsound(context->Device, id) ? AL_TRUE : AL_FALSE;
111 ALCcontext_DecRef(context);
113 return ret;
116 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value)
118 ALCdevice *device;
119 ALCcontext *context;
120 ALfontsound *sound;
121 ALfontsound *link;
123 context = GetContextRef();
124 if(!context) return;
126 device = context->Device;
127 if(!(sound=LookupFontsound(device, id)))
128 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
129 if(sound->ref != 0)
130 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
131 switch(param)
133 case AL_MOD_LFO_TO_PITCH_SOFT:
134 sound->ModLfoToPitch = value;
135 break;
137 case AL_VIBRATO_LFO_TO_PITCH_SOFT:
138 sound->VibratoLfoToPitch = value;
139 break;
141 case AL_MOD_ENV_TO_PITCH_SOFT:
142 sound->ModEnvToPitch = value;
143 break;
145 case AL_FILTER_CUTOFF_SOFT:
146 sound->FilterCutoff = value;
147 break;
149 case AL_FILTER_RESONANCE_SOFT:
150 if(!(value >= 0))
151 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
152 sound->FilterQ = value;
153 break;
155 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT:
156 sound->ModLfoToFilterCutoff = value;
157 break;
159 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT:
160 sound->ModEnvToFilterCutoff = value;
161 break;
163 case AL_MOD_ENV_DELAYTIME_SOFT:
164 sound->ModEnv.DelayTime = value;
165 break;
166 case AL_MOD_ENV_ATTACKTIME_SOFT:
167 sound->ModEnv.AttackTime = value;
168 break;
169 case AL_MOD_ENV_HOLDTIME_SOFT:
170 sound->ModEnv.HoldTime = value;
171 break;
172 case AL_MOD_ENV_DECAYTIME_SOFT:
173 sound->ModEnv.DecayTime = value;
174 break;
175 case AL_MOD_ENV_SUSTAINVOLUME_SOFT:
176 sound->ModEnv.SustainVol = value;
177 break;
178 case AL_MOD_ENV_RELEASETIME_SOFT:
179 sound->ModEnv.ReleaseTime = value;
180 break;
181 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT:
182 sound->ModEnv.KeyToHoldTime = value;
183 break;
184 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT:
185 sound->ModEnv.KeyToDecayTime = value;
186 break;
188 case AL_VOLUME_ENV_DELAYTIME_SOFT:
189 sound->VolEnv.DelayTime = value;
190 break;
191 case AL_VOLUME_ENV_ATTACKTIME_SOFT:
192 sound->VolEnv.AttackTime = value;
193 break;
194 case AL_VOLUME_ENV_HOLDTIME_SOFT:
195 sound->VolEnv.HoldTime = value;
196 break;
197 case AL_VOLUME_ENV_DECAYTIME_SOFT:
198 sound->VolEnv.DecayTime = value;
199 break;
200 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT:
201 sound->VolEnv.SustainVol = value;
202 break;
203 case AL_VOLUME_ENV_RELEASETIME_SOFT:
204 sound->VolEnv.ReleaseTime = value;
205 break;
206 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT:
207 sound->VolEnv.KeyToHoldTime = value;
208 break;
209 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT:
210 sound->VolEnv.KeyToDecayTime = value;
211 break;
213 case AL_SAMPLE_START_SOFT:
214 sound->Start = value;
215 break;
217 case AL_SAMPLE_END_SOFT:
218 sound->End = value;
219 break;
221 case AL_SAMPLE_LOOP_START_SOFT:
222 sound->LoopStart = value;
223 break;
225 case AL_SAMPLE_LOOP_END_SOFT:
226 sound->LoopEnd = value;
227 break;
229 case AL_SAMPLE_RATE_SOFT:
230 if(!(value > 0))
231 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
232 sound->SampleRate = value;
233 break;
235 case AL_LOOP_MODE_SOFT:
236 if(!(value == AL_NONE || value == AL_LOOP_CONTINUOUS_SOFT ||
237 value == AL_LOOP_UNTIL_RELEASE_SOFT))
238 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
239 sound->LoopMode = value;
240 break;
242 case AL_BASE_KEY_SOFT:
243 if(!((value >= 0 && value <= 127) || value == 255))
244 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
245 sound->PitchKey = value;
246 break;
248 case AL_KEY_CORRECTION_SOFT:
249 if(!(value > -100 && value < 100))
250 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
251 sound->PitchCorrection = value;
252 break;
254 case AL_SAMPLE_TYPE_SOFT:
255 if(!(value >= 1 && value <= 4))
256 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
257 sound->SampleType = value;
258 break;
260 case AL_FONTSOUND_LINK_SOFT:
261 if(!value)
262 link = NULL;
263 else
265 link = LookupFontsound(device, value);
266 if(!link)
267 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
269 if(link) IncrementRef(&link->ref);
270 link = ExchangePtr((XchgPtr*)&sound->Link, link);
271 if(link) DecrementRef(&link->ref);
272 break;
274 default:
275 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
278 done:
279 ALCcontext_DecRef(context);
282 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2)
284 ALCdevice *device;
285 ALCcontext *context;
286 ALfontsound *sound;
288 context = GetContextRef();
289 if(!context) return;
291 device = context->Device;
292 if(!(sound=LookupFontsound(device, id)))
293 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
294 if(sound->ref != 0)
295 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
296 switch(param)
298 case AL_KEY_RANGE_SOFT:
299 if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127))
300 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
301 sound->MinKey = value1;
302 sound->MaxKey = value2;
303 break;
305 case AL_VELOCITY_RANGE_SOFT:
306 if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127))
307 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
308 sound->MinVelocity = value1;
309 sound->MaxVelocity = value2;
310 break;
312 default:
313 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
316 done:
317 ALCcontext_DecRef(context);
320 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values)
322 ALCdevice *device;
323 ALCcontext *context;
324 ALfontsound *sound;
326 switch(param)
328 case AL_KEY_RANGE_SOFT:
329 case AL_VELOCITY_RANGE_SOFT:
330 alFontsound2iSOFT(id, param, values[0], values[1]);
331 return;
333 case AL_MOD_LFO_TO_PITCH_SOFT:
334 case AL_VIBRATO_LFO_TO_PITCH_SOFT:
335 case AL_MOD_ENV_TO_PITCH_SOFT:
336 case AL_FILTER_CUTOFF_SOFT:
337 case AL_FILTER_RESONANCE_SOFT:
338 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT:
339 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT:
340 case AL_MOD_ENV_DELAYTIME_SOFT:
341 case AL_MOD_ENV_ATTACKTIME_SOFT:
342 case AL_MOD_ENV_HOLDTIME_SOFT:
343 case AL_MOD_ENV_DECAYTIME_SOFT:
344 case AL_MOD_ENV_SUSTAINVOLUME_SOFT:
345 case AL_MOD_ENV_RELEASETIME_SOFT:
346 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT:
347 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT:
348 case AL_VOLUME_ENV_DELAYTIME_SOFT:
349 case AL_VOLUME_ENV_ATTACKTIME_SOFT:
350 case AL_VOLUME_ENV_HOLDTIME_SOFT:
351 case AL_VOLUME_ENV_DECAYTIME_SOFT:
352 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT:
353 case AL_VOLUME_ENV_RELEASETIME_SOFT:
354 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT:
355 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT:
356 case AL_SAMPLE_START_SOFT:
357 case AL_SAMPLE_END_SOFT:
358 case AL_SAMPLE_LOOP_START_SOFT:
359 case AL_SAMPLE_LOOP_END_SOFT:
360 case AL_SAMPLE_RATE_SOFT:
361 case AL_LOOP_MODE_SOFT:
362 case AL_BASE_KEY_SOFT:
363 case AL_KEY_CORRECTION_SOFT:
364 case AL_SAMPLE_TYPE_SOFT:
365 case AL_FONTSOUND_LINK_SOFT:
366 alFontsoundiSOFT(id, param, values[0]);
367 return;
370 context = GetContextRef();
371 if(!context) return;
373 device = context->Device;
374 if(!(sound=LookupFontsound(device, id)))
375 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
376 if(sound->ref != 0)
377 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
378 switch(param)
380 default:
381 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
384 done:
385 ALCcontext_DecRef(context);
388 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values)
390 ALCdevice *device;
391 ALCcontext *context;
392 const ALfontsound *sound;
394 context = GetContextRef();
395 if(!context) return;
397 device = context->Device;
398 if(!(sound=LookupFontsound(device, id)))
399 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
400 switch(param)
402 case AL_MOD_LFO_TO_PITCH_SOFT:
403 values[0] = sound->ModLfoToPitch;
404 break;
406 case AL_VIBRATO_LFO_TO_PITCH_SOFT:
407 values[0] = sound->VibratoLfoToPitch;
408 break;
410 case AL_MOD_ENV_TO_PITCH_SOFT:
411 values[0] = sound->ModEnvToPitch;
412 break;
414 case AL_FILTER_CUTOFF_SOFT:
415 values[0] = sound->FilterCutoff;
416 break;
418 case AL_FILTER_RESONANCE_SOFT:
419 values[0] = sound->FilterQ;
420 break;
422 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT:
423 values[0] = sound->ModLfoToFilterCutoff;
424 break;
426 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT:
427 values[0] = sound->ModEnvToFilterCutoff;
428 break;
430 case AL_MOD_ENV_DELAYTIME_SOFT:
431 values[0] = sound->ModEnv.DelayTime;
432 break;
433 case AL_MOD_ENV_ATTACKTIME_SOFT:
434 values[0] = sound->ModEnv.AttackTime;
435 break;
436 case AL_MOD_ENV_HOLDTIME_SOFT:
437 values[0] = sound->ModEnv.HoldTime;
438 break;
439 case AL_MOD_ENV_DECAYTIME_SOFT:
440 values[0] = sound->ModEnv.DecayTime;
441 break;
442 case AL_MOD_ENV_SUSTAINVOLUME_SOFT:
443 values[0] = sound->ModEnv.SustainVol;
444 break;
445 case AL_MOD_ENV_RELEASETIME_SOFT:
446 values[0] = sound->ModEnv.ReleaseTime;
447 break;
448 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT:
449 values[0] = sound->ModEnv.KeyToHoldTime;
450 break;
451 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT:
452 values[0] = sound->ModEnv.KeyToDecayTime;
453 break;
455 case AL_VOLUME_ENV_DELAYTIME_SOFT:
456 values[0] = sound->VolEnv.DelayTime;
457 break;
458 case AL_VOLUME_ENV_ATTACKTIME_SOFT:
459 values[0] = sound->VolEnv.AttackTime;
460 break;
461 case AL_VOLUME_ENV_HOLDTIME_SOFT:
462 values[0] = sound->VolEnv.HoldTime;
463 break;
464 case AL_VOLUME_ENV_DECAYTIME_SOFT:
465 values[0] = sound->VolEnv.DecayTime;
466 break;
467 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT:
468 values[0] = sound->VolEnv.SustainVol;
469 break;
470 case AL_VOLUME_ENV_RELEASETIME_SOFT:
471 values[0] = sound->VolEnv.ReleaseTime;
472 break;
473 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT:
474 values[0] = sound->VolEnv.KeyToHoldTime;
475 break;
476 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT:
477 values[0] = sound->VolEnv.KeyToDecayTime;
478 break;
480 case AL_KEY_RANGE_SOFT:
481 values[0] = sound->MinKey;
482 values[1] = sound->MaxKey;
483 break;
485 case AL_VELOCITY_RANGE_SOFT:
486 values[0] = sound->MinVelocity;
487 values[1] = sound->MaxVelocity;
488 break;
490 case AL_SAMPLE_START_SOFT:
491 values[0] = sound->Start;
492 break;
494 case AL_SAMPLE_END_SOFT:
495 values[0] = sound->End;
496 break;
498 case AL_SAMPLE_LOOP_START_SOFT:
499 values[0] = sound->LoopStart;
500 break;
502 case AL_SAMPLE_LOOP_END_SOFT:
503 values[0] = sound->LoopEnd;
504 break;
506 case AL_SAMPLE_RATE_SOFT:
507 values[0] = sound->SampleRate;
508 break;
510 case AL_LOOP_MODE_SOFT:
511 values[0] = sound->LoopMode;
512 break;
514 case AL_BASE_KEY_SOFT:
515 values[0] = sound->PitchKey;
516 break;
518 case AL_KEY_CORRECTION_SOFT:
519 values[0] = sound->PitchCorrection;
520 break;
522 case AL_SAMPLE_TYPE_SOFT:
523 values[0] = sound->SampleType;
524 break;
526 case AL_FONTSOUND_LINK_SOFT:
527 values[0] = (sound->Link ? sound->Link->id : 0);
528 break;
530 default:
531 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
534 done:
535 ALCcontext_DecRef(context);
539 /* ReleaseALFontsounds
541 * Called to destroy any fontsounds that still exist on the device
543 void ReleaseALFontsounds(ALCdevice *device)
545 ALsizei i;
546 for(i = 0;i < device->FontsoundMap.size;i++)
548 ALfontsound *temp = device->FontsoundMap.array[i].value;
549 device->FontsoundMap.array[i].value = NULL;
551 ALfontsound_Destruct(temp);
553 memset(temp, 0, sizeof(*temp));
554 free(temp);