Use gettimeofday if clock_gettime isn't available
[openal-soft.git] / OpenAL32 / alFontsound.c
blob94cf3064393df578adcb45b260983016e6a36b8b
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);
18 static void ALfontsound_Construct(ALfontsound *self);
19 void ALfontsound_Destruct(ALfontsound *self);
20 void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value);
21 static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage);
22 void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value);
23 static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values);
26 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids)
28 ALCcontext *context;
29 ALsizei cur = 0;
31 context = GetContextRef();
32 if(!context) return;
34 if(!(n >= 0))
35 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
37 for(cur = 0;cur < n;cur++)
39 ALfontsound *sound = NewFontsound(context);
40 if(!sound)
42 alDeleteFontsoundsSOFT(cur, ids);
43 break;
46 ids[cur] = sound->id;
49 done:
50 ALCcontext_DecRef(context);
53 AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids)
55 ALCdevice *device;
56 ALCcontext *context;
57 ALfontsound *inst;
58 ALsizei i;
60 context = GetContextRef();
61 if(!context) return;
63 if(!(n >= 0))
64 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
66 device = context->Device;
67 for(i = 0;i < n;i++)
69 /* Check for valid ID */
70 if((inst=LookupFontsound(device, ids[i])) == NULL)
71 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
72 if(inst->ref != 0)
73 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
76 for(i = 0;i < n;i++)
78 if((inst=RemoveFontsound(device, ids[i])) == NULL)
79 continue;
81 ALfontsound_Destruct(inst);
83 memset(inst, 0, sizeof(*inst));
84 free(inst);
87 done:
88 ALCcontext_DecRef(context);
91 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id)
93 ALCcontext *context;
94 ALboolean ret;
96 context = GetContextRef();
97 if(!context) return AL_FALSE;
99 ret = LookupFontsound(context->Device, id) ? AL_TRUE : AL_FALSE;
101 ALCcontext_DecRef(context);
103 return ret;
106 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value)
108 ALCdevice *device;
109 ALCcontext *context;
110 ALfontsound *sound;
112 context = GetContextRef();
113 if(!context) return;
115 device = context->Device;
116 if(!(sound=LookupFontsound(device, id)))
117 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
118 if(sound->ref != 0)
119 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
121 ALfontsound_setPropi(sound, context, param, value);
123 done:
124 ALCcontext_DecRef(context);
127 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2)
129 ALCdevice *device;
130 ALCcontext *context;
131 ALfontsound *sound;
133 context = GetContextRef();
134 if(!context) return;
136 device = context->Device;
137 if(!(sound=LookupFontsound(device, id)))
138 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
139 if(sound->ref != 0)
140 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
141 switch(param)
143 case AL_KEY_RANGE_SOFT:
144 if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1))
145 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
146 sound->MinKey = value1;
147 sound->MaxKey = value2;
148 break;
150 case AL_VELOCITY_RANGE_SOFT:
151 if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1))
152 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
153 sound->MinVelocity = value1;
154 sound->MaxVelocity = value2;
155 break;
157 default:
158 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
161 done:
162 ALCcontext_DecRef(context);
165 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values)
167 ALCdevice *device;
168 ALCcontext *context;
169 ALfontsound *sound;
171 switch(param)
173 case AL_KEY_RANGE_SOFT:
174 case AL_VELOCITY_RANGE_SOFT:
175 alFontsound2iSOFT(id, param, values[0], values[1]);
176 return;
178 case AL_MOD_LFO_TO_PITCH_SOFT:
179 case AL_VIBRATO_LFO_TO_PITCH_SOFT:
180 case AL_MOD_ENV_TO_PITCH_SOFT:
181 case AL_FILTER_CUTOFF_SOFT:
182 case AL_FILTER_RESONANCE_SOFT:
183 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT:
184 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT:
185 case AL_MOD_LFO_TO_VOLUME_SOFT:
186 case AL_CHORUS_SEND_SOFT:
187 case AL_REVERB_SEND_SOFT:
188 case AL_PAN_SOFT:
189 case AL_MOD_LFO_DELAY_SOFT:
190 case AL_MOD_LFO_FREQUENCY_SOFT:
191 case AL_VIBRATO_LFO_DELAY_SOFT:
192 case AL_VIBRATO_LFO_FREQUENCY_SOFT:
193 case AL_MOD_ENV_DELAYTIME_SOFT:
194 case AL_MOD_ENV_ATTACKTIME_SOFT:
195 case AL_MOD_ENV_HOLDTIME_SOFT:
196 case AL_MOD_ENV_DECAYTIME_SOFT:
197 case AL_MOD_ENV_SUSTAINVOLUME_SOFT:
198 case AL_MOD_ENV_RELEASETIME_SOFT:
199 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT:
200 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT:
201 case AL_VOLUME_ENV_DELAYTIME_SOFT:
202 case AL_VOLUME_ENV_ATTACKTIME_SOFT:
203 case AL_VOLUME_ENV_HOLDTIME_SOFT:
204 case AL_VOLUME_ENV_DECAYTIME_SOFT:
205 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT:
206 case AL_VOLUME_ENV_RELEASETIME_SOFT:
207 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT:
208 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT:
209 case AL_ATTENUATION_SOFT:
210 case AL_TUNING_COARSE_SOFT:
211 case AL_TUNING_FINE_SOFT:
212 case AL_LOOP_MODE_SOFT:
213 case AL_TUNING_SCALE_SOFT:
214 case AL_EXCLUSIVE_CLASS_SOFT:
215 case AL_SAMPLE_START_SOFT:
216 case AL_SAMPLE_END_SOFT:
217 case AL_SAMPLE_LOOP_START_SOFT:
218 case AL_SAMPLE_LOOP_END_SOFT:
219 case AL_SAMPLE_RATE_SOFT:
220 case AL_BASE_KEY_SOFT:
221 case AL_KEY_CORRECTION_SOFT:
222 case AL_SAMPLE_TYPE_SOFT:
223 case AL_FONTSOUND_LINK_SOFT:
224 alFontsoundiSOFT(id, param, values[0]);
225 return;
228 context = GetContextRef();
229 if(!context) return;
231 device = context->Device;
232 if(!(sound=LookupFontsound(device, id)))
233 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
234 if(sound->ref != 0)
235 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
236 switch(param)
238 default:
239 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
242 done:
243 ALCcontext_DecRef(context);
246 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values)
248 ALCdevice *device;
249 ALCcontext *context;
250 const ALfontsound *sound;
252 context = GetContextRef();
253 if(!context) return;
255 device = context->Device;
256 if(!(sound=LookupFontsound(device, id)))
257 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
258 switch(param)
260 case AL_MOD_LFO_TO_PITCH_SOFT:
261 values[0] = sound->ModLfoToPitch;
262 break;
264 case AL_VIBRATO_LFO_TO_PITCH_SOFT:
265 values[0] = sound->VibratoLfoToPitch;
266 break;
268 case AL_MOD_ENV_TO_PITCH_SOFT:
269 values[0] = sound->ModEnvToPitch;
270 break;
272 case AL_FILTER_CUTOFF_SOFT:
273 values[0] = sound->FilterCutoff;
274 break;
276 case AL_FILTER_RESONANCE_SOFT:
277 values[0] = sound->FilterQ;
278 break;
280 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT:
281 values[0] = sound->ModLfoToFilterCutoff;
282 break;
284 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT:
285 values[0] = sound->ModEnvToFilterCutoff;
286 break;
288 case AL_MOD_LFO_TO_VOLUME_SOFT:
289 values[0] = sound->ModLfoToVolume;
290 break;
292 case AL_CHORUS_SEND_SOFT:
293 values[0] = sound->ChorusSend;
294 break;
296 case AL_REVERB_SEND_SOFT:
297 values[0] = sound->ReverbSend;
298 break;
300 case AL_PAN_SOFT:
301 values[0] = sound->Pan;
302 break;
304 case AL_MOD_LFO_DELAY_SOFT:
305 values[0] = sound->ModLfo.Delay;
306 break;
307 case AL_MOD_LFO_FREQUENCY_SOFT:
308 values[0] = sound->ModLfo.Frequency;
309 break;
311 case AL_VIBRATO_LFO_DELAY_SOFT:
312 values[0] = sound->VibratoLfo.Delay;
313 break;
314 case AL_VIBRATO_LFO_FREQUENCY_SOFT:
315 values[0] = sound->VibratoLfo.Frequency;
316 break;
318 case AL_MOD_ENV_DELAYTIME_SOFT:
319 values[0] = sound->ModEnv.DelayTime;
320 break;
321 case AL_MOD_ENV_ATTACKTIME_SOFT:
322 values[0] = sound->ModEnv.AttackTime;
323 break;
324 case AL_MOD_ENV_HOLDTIME_SOFT:
325 values[0] = sound->ModEnv.HoldTime;
326 break;
327 case AL_MOD_ENV_DECAYTIME_SOFT:
328 values[0] = sound->ModEnv.DecayTime;
329 break;
330 case AL_MOD_ENV_SUSTAINVOLUME_SOFT:
331 values[0] = sound->ModEnv.SustainAttn;
332 break;
333 case AL_MOD_ENV_RELEASETIME_SOFT:
334 values[0] = sound->ModEnv.ReleaseTime;
335 break;
336 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT:
337 values[0] = sound->ModEnv.KeyToHoldTime;
338 break;
339 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT:
340 values[0] = sound->ModEnv.KeyToDecayTime;
341 break;
343 case AL_VOLUME_ENV_DELAYTIME_SOFT:
344 values[0] = sound->VolEnv.DelayTime;
345 break;
346 case AL_VOLUME_ENV_ATTACKTIME_SOFT:
347 values[0] = sound->VolEnv.AttackTime;
348 break;
349 case AL_VOLUME_ENV_HOLDTIME_SOFT:
350 values[0] = sound->VolEnv.HoldTime;
351 break;
352 case AL_VOLUME_ENV_DECAYTIME_SOFT:
353 values[0] = sound->VolEnv.DecayTime;
354 break;
355 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT:
356 values[0] = sound->VolEnv.SustainAttn;
357 break;
358 case AL_VOLUME_ENV_RELEASETIME_SOFT:
359 values[0] = sound->VolEnv.ReleaseTime;
360 break;
361 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT:
362 values[0] = sound->VolEnv.KeyToHoldTime;
363 break;
364 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT:
365 values[0] = sound->VolEnv.KeyToDecayTime;
366 break;
368 case AL_KEY_RANGE_SOFT:
369 values[0] = sound->MinKey;
370 values[1] = sound->MaxKey;
371 break;
373 case AL_VELOCITY_RANGE_SOFT:
374 values[0] = sound->MinVelocity;
375 values[1] = sound->MaxVelocity;
376 break;
378 case AL_ATTENUATION_SOFT:
379 values[0] = sound->Attenuation;
380 break;
382 case AL_TUNING_COARSE_SOFT:
383 values[0] = sound->CoarseTuning;
384 break;
385 case AL_TUNING_FINE_SOFT:
386 values[0] = sound->FineTuning;
387 break;
389 case AL_LOOP_MODE_SOFT:
390 values[0] = sound->LoopMode;
391 break;
393 case AL_TUNING_SCALE_SOFT:
394 values[0] = sound->TuningScale;
395 break;
397 case AL_EXCLUSIVE_CLASS_SOFT:
398 values[0] = sound->ExclusiveClass;
399 break;
401 case AL_SAMPLE_START_SOFT:
402 values[0] = sound->Start;
403 break;
405 case AL_SAMPLE_END_SOFT:
406 values[0] = sound->End;
407 break;
409 case AL_SAMPLE_LOOP_START_SOFT:
410 values[0] = sound->LoopStart;
411 break;
413 case AL_SAMPLE_LOOP_END_SOFT:
414 values[0] = sound->LoopEnd;
415 break;
417 case AL_SAMPLE_RATE_SOFT:
418 values[0] = sound->SampleRate;
419 break;
421 case AL_BASE_KEY_SOFT:
422 values[0] = sound->PitchKey;
423 break;
425 case AL_KEY_CORRECTION_SOFT:
426 values[0] = sound->PitchCorrection;
427 break;
429 case AL_SAMPLE_TYPE_SOFT:
430 values[0] = sound->SampleType;
431 break;
433 case AL_FONTSOUND_LINK_SOFT:
434 values[0] = (sound->Link ? sound->Link->id : 0);
435 break;
437 default:
438 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
441 done:
442 ALCcontext_DecRef(context);
445 AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value)
447 ALCdevice *device;
448 ALCcontext *context;
449 ALfontsound *sound;
451 context = GetContextRef();
452 if(!context) return;
454 device = context->Device;
455 if(!(sound=LookupFontsound(device, id)))
456 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
457 ALfontsound_setModStagei(sound, context, stage, param, value);
459 done:
460 ALCcontext_DecRef(context);
463 AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values)
465 ALCdevice *device;
466 ALCcontext *context;
467 ALfontsound *sound;
469 context = GetContextRef();
470 if(!context) return;
472 device = context->Device;
473 if(!(sound=LookupFontsound(device, id)))
474 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
475 ALfontsound_getModStagei(sound, context, stage, param, values);
477 done:
478 ALCcontext_DecRef(context);
482 ALfontsound *NewFontsound(ALCcontext *context)
484 ALCdevice *device = context->Device;
485 ALfontsound *sound;
486 ALenum err;
488 sound = calloc(1, sizeof(*sound));
489 if(!sound)
490 SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL);
491 ALfontsound_Construct(sound);
493 err = NewThunkEntry(&sound->id);
494 if(err == AL_NO_ERROR)
495 err = InsertUIntMapEntry(&device->FontsoundMap, sound->id, sound);
496 if(err != AL_NO_ERROR)
498 ALfontsound_Destruct(sound);
499 memset(sound, 0, sizeof(*sound));
500 free(sound);
502 SET_ERROR_AND_RETURN_VALUE(context, err, NULL);
505 return sound;
509 static void ALfontsound_Construct(ALfontsound *self)
511 self->ref = 0;
513 self->MinKey = 0;
514 self->MaxKey = 127;
515 self->MinVelocity = 0;
516 self->MaxVelocity = 127;
518 self->ModLfoToPitch = 0;
519 self->VibratoLfoToPitch = 0;
520 self->ModEnvToPitch = 0;
522 self->FilterCutoff = 13500;
523 self->FilterQ = 0;
524 self->ModLfoToFilterCutoff = 0;
525 self->ModEnvToFilterCutoff = 0;
526 self->ModLfoToVolume = 0;
528 self->ChorusSend = 0;
529 self->ReverbSend = 0;
531 self->Pan = 0;
533 self->ModLfo.Delay = 0;
534 self->ModLfo.Frequency = 0;
536 self->VibratoLfo.Delay = 0;
537 self->VibratoLfo.Frequency = 0;
539 self->ModEnv.DelayTime = -12000;
540 self->ModEnv.AttackTime = -12000;
541 self->ModEnv.HoldTime = -12000;
542 self->ModEnv.DecayTime = -12000;
543 self->ModEnv.SustainAttn = 0;
544 self->ModEnv.ReleaseTime = -12000;
545 self->ModEnv.KeyToHoldTime = 0;
546 self->ModEnv.KeyToDecayTime = 0;
548 self->VolEnv.DelayTime = -12000;
549 self->VolEnv.AttackTime = -12000;
550 self->VolEnv.HoldTime = -12000;
551 self->VolEnv.DecayTime = -12000;
552 self->VolEnv.SustainAttn = 0;
553 self->VolEnv.ReleaseTime = -12000;
554 self->VolEnv.KeyToHoldTime = 0;
555 self->VolEnv.KeyToDecayTime = 0;
557 self->Attenuation = 0;
559 self->CoarseTuning = 0;
560 self->FineTuning = 0;
562 self->LoopMode = AL_NONE;
564 self->TuningScale = 100;
566 self->ExclusiveClass = 0;
568 self->Start = 0;
569 self->End = 0;
570 self->LoopStart = 0;
571 self->LoopEnd = 0;
572 self->SampleRate = 0;
573 self->PitchKey = 0;
574 self->PitchCorrection = 0;
575 self->SampleType = AL_MONO_SOFT;
576 self->Link = NULL;
578 InitUIntMap(&self->ModulatorMap, ~0);
580 self->id = 0;
583 void ALfontsound_Destruct(ALfontsound *self)
585 ALsizei i;
587 FreeThunkEntry(self->id);
588 self->id = 0;
590 if(self->Link)
591 DecrementRef(&self->Link->ref);
592 self->Link = NULL;
594 for(i = 0;i < self->ModulatorMap.size;i++)
596 free(self->ModulatorMap.array[i].value);
597 self->ModulatorMap.array[i].value = NULL;
599 ResetUIntMap(&self->ModulatorMap);
602 void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value)
604 ALfontsound *link;
606 switch(param)
608 case AL_MOD_LFO_TO_PITCH_SOFT:
609 self->ModLfoToPitch = value;
610 break;
612 case AL_VIBRATO_LFO_TO_PITCH_SOFT:
613 self->VibratoLfoToPitch = value;
614 break;
616 case AL_MOD_ENV_TO_PITCH_SOFT:
617 self->ModEnvToPitch = value;
618 break;
620 case AL_FILTER_CUTOFF_SOFT:
621 self->FilterCutoff = value;
622 break;
624 case AL_FILTER_RESONANCE_SOFT:
625 if(!(value >= 0))
626 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
627 self->FilterQ = value;
628 break;
630 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT:
631 self->ModLfoToFilterCutoff = value;
632 break;
634 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT:
635 self->ModEnvToFilterCutoff = value;
636 break;
638 case AL_MOD_LFO_TO_VOLUME_SOFT:
639 self->ModLfoToVolume = value;
640 break;
642 case AL_CHORUS_SEND_SOFT:
643 if(!(value >= 0 && value <= 1000))
644 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
645 self->ChorusSend = value;
646 break;
647 case AL_REVERB_SEND_SOFT:
648 if(!(value >= 0 && value <= 1000))
649 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
650 self->ReverbSend = value;
651 break;
653 case AL_PAN_SOFT:
654 self->Pan = value;
655 break;
657 case AL_MOD_LFO_DELAY_SOFT:
658 self->ModLfo.Delay = value;
659 break;
660 case AL_MOD_LFO_FREQUENCY_SOFT:
661 self->ModLfo.Frequency = value;
662 break;
664 case AL_VIBRATO_LFO_DELAY_SOFT:
665 self->VibratoLfo.Delay = value;
666 break;
667 case AL_VIBRATO_LFO_FREQUENCY_SOFT:
668 self->VibratoLfo.Frequency = value;
669 break;
671 case AL_MOD_ENV_DELAYTIME_SOFT:
672 self->ModEnv.DelayTime = value;
673 break;
674 case AL_MOD_ENV_ATTACKTIME_SOFT:
675 self->ModEnv.AttackTime = value;
676 break;
677 case AL_MOD_ENV_HOLDTIME_SOFT:
678 self->ModEnv.HoldTime = value;
679 break;
680 case AL_MOD_ENV_DECAYTIME_SOFT:
681 self->ModEnv.DecayTime = value;
682 break;
683 case AL_MOD_ENV_SUSTAINVOLUME_SOFT:
684 self->ModEnv.SustainAttn = value;
685 break;
686 case AL_MOD_ENV_RELEASETIME_SOFT:
687 self->ModEnv.ReleaseTime = value;
688 break;
689 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT:
690 self->ModEnv.KeyToHoldTime = value;
691 break;
692 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT:
693 self->ModEnv.KeyToDecayTime = value;
694 break;
696 case AL_VOLUME_ENV_DELAYTIME_SOFT:
697 self->VolEnv.DelayTime = value;
698 break;
699 case AL_VOLUME_ENV_ATTACKTIME_SOFT:
700 self->VolEnv.AttackTime = value;
701 break;
702 case AL_VOLUME_ENV_HOLDTIME_SOFT:
703 self->VolEnv.HoldTime = value;
704 break;
705 case AL_VOLUME_ENV_DECAYTIME_SOFT:
706 self->VolEnv.DecayTime = value;
707 break;
708 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT:
709 self->VolEnv.SustainAttn = value;
710 break;
711 case AL_VOLUME_ENV_RELEASETIME_SOFT:
712 self->VolEnv.ReleaseTime = value;
713 break;
714 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT:
715 self->VolEnv.KeyToHoldTime = value;
716 break;
717 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT:
718 self->VolEnv.KeyToDecayTime = value;
719 break;
721 case AL_ATTENUATION_SOFT:
722 if(!(value >= 0))
723 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
724 self->Attenuation = value;
725 break;
727 case AL_TUNING_COARSE_SOFT:
728 self->CoarseTuning = value;
729 break;
730 case AL_TUNING_FINE_SOFT:
731 self->FineTuning = value;
732 break;
734 case AL_LOOP_MODE_SOFT:
735 if(!(value == AL_NONE || value == AL_LOOP_CONTINUOUS_SOFT ||
736 value == AL_LOOP_UNTIL_RELEASE_SOFT))
737 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
738 self->LoopMode = value;
739 break;
741 case AL_TUNING_SCALE_SOFT:
742 self->TuningScale = value;
743 break;
745 case AL_EXCLUSIVE_CLASS_SOFT:
746 self->ExclusiveClass = value;
747 break;
749 case AL_SAMPLE_START_SOFT:
750 self->Start = value;
751 break;
753 case AL_SAMPLE_END_SOFT:
754 self->End = value;
755 break;
757 case AL_SAMPLE_LOOP_START_SOFT:
758 self->LoopStart = value;
759 break;
761 case AL_SAMPLE_LOOP_END_SOFT:
762 self->LoopEnd = value;
763 break;
765 case AL_SAMPLE_RATE_SOFT:
766 if(!(value > 0))
767 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
768 self->SampleRate = value;
769 break;
771 case AL_BASE_KEY_SOFT:
772 if(!((value >= 0 && value <= 127) || value == 255))
773 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
774 self->PitchKey = value;
775 break;
777 case AL_KEY_CORRECTION_SOFT:
778 if(!(value >= -99 && value <= 99))
779 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
780 self->PitchCorrection = value;
781 break;
783 case AL_SAMPLE_TYPE_SOFT:
784 if(!(value == AL_MONO_SOFT || value == AL_RIGHT_SOFT || value == AL_LEFT_SOFT))
785 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
786 self->SampleType = value;
787 break;
789 case AL_FONTSOUND_LINK_SOFT:
790 if(!value)
791 link = NULL;
792 else
794 link = LookupFontsound(context->Device, value);
795 if(!link)
796 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
798 if(link) IncrementRef(&link->ref);
799 link = ExchangePtr((XchgPtr*)&self->Link, link);
800 if(link) DecrementRef(&link->ref);
801 break;
803 default:
804 SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
808 static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage)
810 ALsfmodulator *ret = LookupModulator(self, stage);
811 if(!ret)
813 static const ALsfmodulator moddef = {
814 { { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT },
815 { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT }
818 AL_LINEAR_SOFT,
819 AL_NONE
821 ret = malloc(sizeof(*ret));
822 *ret = moddef;
823 InsertUIntMapEntry(&self->ModulatorMap, stage, ret);
825 return ret;
828 void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value)
830 ALint srcidx = 0;
832 if(self->ref != 0)
833 SET_ERROR_AND_RETURN(context, AL_INVALID_OPERATION);
834 switch(param)
836 case AL_SOURCE1_INPUT_SOFT:
837 srcidx++;
838 /* fall-through */
839 case AL_SOURCE0_INPUT_SOFT:
840 if(!(value == AL_ONE_SOFT || value == AL_NOTEON_VELOCITY_SOFT ||
841 value == AL_NOTEON_KEY_SOFT || value == AL_KEYPRESSURE_SOFT ||
842 value == AL_CHANNELPRESSURE_SOFT || value == AL_PITCHBEND_SOFT ||
843 value == AL_PITCHBEND_SENSITIVITY_SOFT ||
844 (value > 0 && value < 120 && !(value == 6 || (value >= 32 && value <= 63) ||
845 (value >= 98 && value <= 101))
848 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
849 ALfontsound_getModStage(self, stage)->Source[srcidx].Input = value;
850 break;
852 case AL_SOURCE1_TYPE_SOFT:
853 srcidx++;
854 /* fall-through */
855 case AL_SOURCE0_TYPE_SOFT:
856 if(!(value == AL_UNORM_SOFT || value == AL_UNORM_REV_SOFT ||
857 value == AL_SNORM_SOFT || value == AL_SNORM_REV_SOFT))
858 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
859 ALfontsound_getModStage(self, stage)->Source[srcidx].Type = value;
860 break;
862 case AL_SOURCE1_FORM_SOFT:
863 srcidx++;
864 /* fall-through */
865 case AL_SOURCE0_FORM_SOFT:
866 if(!(value == AL_LINEAR_SOFT || value == AL_CONCAVE_SOFT ||
867 value == AL_CONVEX_SOFT || value == AL_SWITCH_SOFT))
868 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
869 ALfontsound_getModStage(self, stage)->Source[srcidx].Form = value;
870 break;
872 case AL_AMOUNT_SOFT:
873 ALfontsound_getModStage(self, stage)->Amount = value;
874 break;
876 case AL_TRANSFORM_OP_SOFT:
877 if(!(value == AL_LINEAR_SOFT || value == AL_ABSOLUTE_SOFT))
878 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
879 ALfontsound_getModStage(self, stage)->TransformOp = value;
880 break;
882 case AL_DESTINATION_SOFT:
883 if(!(value == AL_MOD_LFO_TO_PITCH_SOFT || value == AL_VIBRATO_LFO_TO_PITCH_SOFT ||
884 value == AL_MOD_ENV_TO_PITCH_SOFT || value == AL_FILTER_CUTOFF_SOFT ||
885 value == AL_FILTER_RESONANCE_SOFT || value == AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT ||
886 value == AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT || value == AL_MOD_LFO_TO_VOLUME_SOFT ||
887 value == AL_CHORUS_SEND_SOFT || value == AL_REVERB_SEND_SOFT || value == AL_PAN_SOFT ||
888 value == AL_MOD_LFO_DELAY_SOFT || value == AL_MOD_LFO_FREQUENCY_SOFT ||
889 value == AL_VIBRATO_LFO_DELAY_SOFT || value == AL_VIBRATO_LFO_FREQUENCY_SOFT ||
890 value == AL_MOD_ENV_DELAYTIME_SOFT || value == AL_MOD_ENV_ATTACKTIME_SOFT ||
891 value == AL_MOD_ENV_HOLDTIME_SOFT || value == AL_MOD_ENV_DECAYTIME_SOFT ||
892 value == AL_MOD_ENV_SUSTAINVOLUME_SOFT || value == AL_MOD_ENV_RELEASETIME_SOFT ||
893 value == AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT ||
894 value == AL_VOLUME_ENV_DELAYTIME_SOFT || value == AL_VOLUME_ENV_ATTACKTIME_SOFT ||
895 value == AL_VOLUME_ENV_HOLDTIME_SOFT || value == AL_VOLUME_ENV_DECAYTIME_SOFT ||
896 value == AL_VOLUME_ENV_SUSTAINVOLUME_SOFT || value == AL_VOLUME_ENV_RELEASETIME_SOFT ||
897 value == AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT ||
898 value == AL_ATTENUATION_SOFT || value == AL_TUNING_COARSE_SOFT ||
899 value == AL_TUNING_FINE_SOFT || value == AL_TUNING_SCALE_SOFT))
900 SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE);
901 ALfontsound_getModStage(self, stage)->Dest = value;
902 break;
904 default:
905 SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
909 static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values)
911 ALsfmodulator *mod = LookupModulator(self, stage);
912 ALint srcidx = 0;
914 switch(param)
916 case AL_SOURCE1_INPUT_SOFT:
917 srcidx++;
918 /* fall-through */
919 case AL_SOURCE0_INPUT_SOFT:
920 values[0] = mod ? mod->Source[srcidx].Input : AL_ONE_SOFT;
921 break;
923 case AL_SOURCE1_TYPE_SOFT:
924 srcidx++;
925 /* fall-through */
926 case AL_SOURCE0_TYPE_SOFT:
927 values[0] = mod ? mod->Source[srcidx].Type : AL_UNORM_SOFT;
928 break;
930 case AL_SOURCE1_FORM_SOFT:
931 srcidx++;
932 /* fall-through */
933 case AL_SOURCE0_FORM_SOFT:
934 values[0] = mod ? mod->Source[srcidx].Form : AL_LINEAR_SOFT;
935 break;
937 case AL_AMOUNT_SOFT:
938 values[0] = mod ? mod->Amount : 0;
939 break;
941 case AL_TRANSFORM_OP_SOFT:
942 values[0] = mod ? mod->TransformOp : AL_LINEAR_SOFT;
943 break;
945 case AL_DESTINATION_SOFT:
946 values[0] = mod ? mod->Dest : AL_NONE;
947 break;
949 default:
950 SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM);
955 /* ReleaseALFontsounds
957 * Called to destroy any fontsounds that still exist on the device
959 void ReleaseALFontsounds(ALCdevice *device)
961 ALsizei i;
962 for(i = 0;i < device->FontsoundMap.size;i++)
964 ALfontsound *temp = device->FontsoundMap.array[i].value;
965 device->FontsoundMap.array[i].value = NULL;
967 ALfontsound_Destruct(temp);
969 memset(temp, 0, sizeof(*temp));
970 free(temp);