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
)
31 context
= GetContextRef();
35 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
37 for(cur
= 0;cur
< n
;cur
++)
39 ALfontsound
*sound
= NewFontsound(context
);
42 alDeleteFontsoundsSOFT(cur
, ids
);
50 ALCcontext_DecRef(context
);
53 AL_API ALvoid AL_APIENTRY
alDeleteFontsoundsSOFT(ALsizei n
, const ALuint
*ids
)
60 context
= GetContextRef();
64 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
66 device
= context
->Device
;
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(ReadRef(&inst
->ref
) != 0)
73 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
78 if((inst
=RemoveFontsound(device
, ids
[i
])) == NULL
)
81 ALfontsound_Destruct(inst
);
83 memset(inst
, 0, sizeof(*inst
));
88 ALCcontext_DecRef(context
);
91 AL_API ALboolean AL_APIENTRY
alIsFontsoundSOFT(ALuint id
)
96 context
= GetContextRef();
97 if(!context
) return AL_FALSE
;
99 ret
= LookupFontsound(context
->Device
, id
) ? AL_TRUE
: AL_FALSE
;
101 ALCcontext_DecRef(context
);
106 AL_API
void AL_APIENTRY
alFontsoundiSOFT(ALuint id
, ALenum param
, ALint value
)
112 context
= GetContextRef();
115 device
= context
->Device
;
116 if(!(sound
=LookupFontsound(device
, id
)))
117 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
118 if(ReadRef(&sound
->ref
) != 0)
119 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
121 ALfontsound_setPropi(sound
, context
, param
, value
);
124 ALCcontext_DecRef(context
);
127 AL_API
void AL_APIENTRY
alFontsound2iSOFT(ALuint id
, ALenum param
, ALint value1
, ALint value2
)
133 context
= GetContextRef();
136 device
= context
->Device
;
137 if(!(sound
=LookupFontsound(device
, id
)))
138 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
139 if(ReadRef(&sound
->ref
) != 0)
140 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
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
;
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
;
158 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
162 ALCcontext_DecRef(context
);
165 AL_API
void AL_APIENTRY
alFontsoundivSOFT(ALuint id
, ALenum param
, const ALint
*values
)
173 case AL_KEY_RANGE_SOFT
:
174 case AL_VELOCITY_RANGE_SOFT
:
175 alFontsound2iSOFT(id
, param
, values
[0], values
[1]);
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
:
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]);
228 context
= GetContextRef();
231 device
= context
->Device
;
232 if(!(sound
=LookupFontsound(device
, id
)))
233 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
234 if(ReadRef(&sound
->ref
) != 0)
235 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
239 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
243 ALCcontext_DecRef(context
);
246 AL_API
void AL_APIENTRY
alGetFontsoundivSOFT(ALuint id
, ALenum param
, ALint
*values
)
250 const ALfontsound
*sound
;
252 context
= GetContextRef();
255 device
= context
->Device
;
256 if(!(sound
=LookupFontsound(device
, id
)))
257 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
260 case AL_MOD_LFO_TO_PITCH_SOFT
:
261 values
[0] = sound
->ModLfoToPitch
;
264 case AL_VIBRATO_LFO_TO_PITCH_SOFT
:
265 values
[0] = sound
->VibratoLfoToPitch
;
268 case AL_MOD_ENV_TO_PITCH_SOFT
:
269 values
[0] = sound
->ModEnvToPitch
;
272 case AL_FILTER_CUTOFF_SOFT
:
273 values
[0] = sound
->FilterCutoff
;
276 case AL_FILTER_RESONANCE_SOFT
:
277 values
[0] = sound
->FilterQ
;
280 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
:
281 values
[0] = sound
->ModLfoToFilterCutoff
;
284 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
:
285 values
[0] = sound
->ModEnvToFilterCutoff
;
288 case AL_MOD_LFO_TO_VOLUME_SOFT
:
289 values
[0] = sound
->ModLfoToVolume
;
292 case AL_CHORUS_SEND_SOFT
:
293 values
[0] = sound
->ChorusSend
;
296 case AL_REVERB_SEND_SOFT
:
297 values
[0] = sound
->ReverbSend
;
301 values
[0] = sound
->Pan
;
304 case AL_MOD_LFO_DELAY_SOFT
:
305 values
[0] = sound
->ModLfo
.Delay
;
307 case AL_MOD_LFO_FREQUENCY_SOFT
:
308 values
[0] = sound
->ModLfo
.Frequency
;
311 case AL_VIBRATO_LFO_DELAY_SOFT
:
312 values
[0] = sound
->VibratoLfo
.Delay
;
314 case AL_VIBRATO_LFO_FREQUENCY_SOFT
:
315 values
[0] = sound
->VibratoLfo
.Frequency
;
318 case AL_MOD_ENV_DELAYTIME_SOFT
:
319 values
[0] = sound
->ModEnv
.DelayTime
;
321 case AL_MOD_ENV_ATTACKTIME_SOFT
:
322 values
[0] = sound
->ModEnv
.AttackTime
;
324 case AL_MOD_ENV_HOLDTIME_SOFT
:
325 values
[0] = sound
->ModEnv
.HoldTime
;
327 case AL_MOD_ENV_DECAYTIME_SOFT
:
328 values
[0] = sound
->ModEnv
.DecayTime
;
330 case AL_MOD_ENV_SUSTAINVOLUME_SOFT
:
331 values
[0] = sound
->ModEnv
.SustainAttn
;
333 case AL_MOD_ENV_RELEASETIME_SOFT
:
334 values
[0] = sound
->ModEnv
.ReleaseTime
;
336 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
:
337 values
[0] = sound
->ModEnv
.KeyToHoldTime
;
339 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
:
340 values
[0] = sound
->ModEnv
.KeyToDecayTime
;
343 case AL_VOLUME_ENV_DELAYTIME_SOFT
:
344 values
[0] = sound
->VolEnv
.DelayTime
;
346 case AL_VOLUME_ENV_ATTACKTIME_SOFT
:
347 values
[0] = sound
->VolEnv
.AttackTime
;
349 case AL_VOLUME_ENV_HOLDTIME_SOFT
:
350 values
[0] = sound
->VolEnv
.HoldTime
;
352 case AL_VOLUME_ENV_DECAYTIME_SOFT
:
353 values
[0] = sound
->VolEnv
.DecayTime
;
355 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
:
356 values
[0] = sound
->VolEnv
.SustainAttn
;
358 case AL_VOLUME_ENV_RELEASETIME_SOFT
:
359 values
[0] = sound
->VolEnv
.ReleaseTime
;
361 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
:
362 values
[0] = sound
->VolEnv
.KeyToHoldTime
;
364 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
:
365 values
[0] = sound
->VolEnv
.KeyToDecayTime
;
368 case AL_KEY_RANGE_SOFT
:
369 values
[0] = sound
->MinKey
;
370 values
[1] = sound
->MaxKey
;
373 case AL_VELOCITY_RANGE_SOFT
:
374 values
[0] = sound
->MinVelocity
;
375 values
[1] = sound
->MaxVelocity
;
378 case AL_ATTENUATION_SOFT
:
379 values
[0] = sound
->Attenuation
;
382 case AL_TUNING_COARSE_SOFT
:
383 values
[0] = sound
->CoarseTuning
;
385 case AL_TUNING_FINE_SOFT
:
386 values
[0] = sound
->FineTuning
;
389 case AL_LOOP_MODE_SOFT
:
390 values
[0] = sound
->LoopMode
;
393 case AL_TUNING_SCALE_SOFT
:
394 values
[0] = sound
->TuningScale
;
397 case AL_EXCLUSIVE_CLASS_SOFT
:
398 values
[0] = sound
->ExclusiveClass
;
401 case AL_SAMPLE_START_SOFT
:
402 values
[0] = sound
->Start
;
405 case AL_SAMPLE_END_SOFT
:
406 values
[0] = sound
->End
;
409 case AL_SAMPLE_LOOP_START_SOFT
:
410 values
[0] = sound
->LoopStart
;
413 case AL_SAMPLE_LOOP_END_SOFT
:
414 values
[0] = sound
->LoopEnd
;
417 case AL_SAMPLE_RATE_SOFT
:
418 values
[0] = sound
->SampleRate
;
421 case AL_BASE_KEY_SOFT
:
422 values
[0] = sound
->PitchKey
;
425 case AL_KEY_CORRECTION_SOFT
:
426 values
[0] = sound
->PitchCorrection
;
429 case AL_SAMPLE_TYPE_SOFT
:
430 values
[0] = sound
->SampleType
;
433 case AL_FONTSOUND_LINK_SOFT
:
434 values
[0] = (sound
->Link
? sound
->Link
->id
: 0);
438 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
442 ALCcontext_DecRef(context
);
445 AL_API
void AL_APIENTRY
alFontsoundModulatoriSOFT(ALuint id
, ALsizei stage
, ALenum param
, ALint value
)
451 context
= GetContextRef();
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
);
460 ALCcontext_DecRef(context
);
463 AL_API
void AL_APIENTRY
alGetFontsoundModulatorivSOFT(ALuint id
, ALsizei stage
, ALenum param
, ALint
*values
)
469 context
= GetContextRef();
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
);
478 ALCcontext_DecRef(context
);
482 ALfontsound
*NewFontsound(ALCcontext
*context
)
484 ALCdevice
*device
= context
->Device
;
488 sound
= calloc(1, sizeof(*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
));
502 SET_ERROR_AND_RETURN_VALUE(context
, err
, NULL
);
509 static void ALfontsound_Construct(ALfontsound
*self
)
511 InitRef(&self
->ref
, 0);
515 self
->MinVelocity
= 0;
516 self
->MaxVelocity
= 127;
518 self
->ModLfoToPitch
= 0;
519 self
->VibratoLfoToPitch
= 0;
520 self
->ModEnvToPitch
= 0;
522 self
->FilterCutoff
= 13500;
524 self
->ModLfoToFilterCutoff
= 0;
525 self
->ModEnvToFilterCutoff
= 0;
526 self
->ModLfoToVolume
= 0;
528 self
->ChorusSend
= 0;
529 self
->ReverbSend
= 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;
572 self
->SampleRate
= 0;
574 self
->PitchCorrection
= 0;
575 self
->SampleType
= AL_MONO_SOFT
;
578 InitUIntMap(&self
->ModulatorMap
, ~0);
583 void ALfontsound_Destruct(ALfontsound
*self
)
587 FreeThunkEntry(self
->id
);
591 DecrementRef(&self
->Link
->ref
);
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
)
608 case AL_MOD_LFO_TO_PITCH_SOFT
:
609 self
->ModLfoToPitch
= value
;
612 case AL_VIBRATO_LFO_TO_PITCH_SOFT
:
613 self
->VibratoLfoToPitch
= value
;
616 case AL_MOD_ENV_TO_PITCH_SOFT
:
617 self
->ModEnvToPitch
= value
;
620 case AL_FILTER_CUTOFF_SOFT
:
621 self
->FilterCutoff
= value
;
624 case AL_FILTER_RESONANCE_SOFT
:
626 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
627 self
->FilterQ
= value
;
630 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
:
631 self
->ModLfoToFilterCutoff
= value
;
634 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
:
635 self
->ModEnvToFilterCutoff
= value
;
638 case AL_MOD_LFO_TO_VOLUME_SOFT
:
639 self
->ModLfoToVolume
= value
;
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
;
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
;
657 case AL_MOD_LFO_DELAY_SOFT
:
658 self
->ModLfo
.Delay
= value
;
660 case AL_MOD_LFO_FREQUENCY_SOFT
:
661 self
->ModLfo
.Frequency
= value
;
664 case AL_VIBRATO_LFO_DELAY_SOFT
:
665 self
->VibratoLfo
.Delay
= value
;
667 case AL_VIBRATO_LFO_FREQUENCY_SOFT
:
668 self
->VibratoLfo
.Frequency
= value
;
671 case AL_MOD_ENV_DELAYTIME_SOFT
:
672 self
->ModEnv
.DelayTime
= value
;
674 case AL_MOD_ENV_ATTACKTIME_SOFT
:
675 self
->ModEnv
.AttackTime
= value
;
677 case AL_MOD_ENV_HOLDTIME_SOFT
:
678 self
->ModEnv
.HoldTime
= value
;
680 case AL_MOD_ENV_DECAYTIME_SOFT
:
681 self
->ModEnv
.DecayTime
= value
;
683 case AL_MOD_ENV_SUSTAINVOLUME_SOFT
:
684 self
->ModEnv
.SustainAttn
= value
;
686 case AL_MOD_ENV_RELEASETIME_SOFT
:
687 self
->ModEnv
.ReleaseTime
= value
;
689 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
:
690 self
->ModEnv
.KeyToHoldTime
= value
;
692 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
:
693 self
->ModEnv
.KeyToDecayTime
= value
;
696 case AL_VOLUME_ENV_DELAYTIME_SOFT
:
697 self
->VolEnv
.DelayTime
= value
;
699 case AL_VOLUME_ENV_ATTACKTIME_SOFT
:
700 self
->VolEnv
.AttackTime
= value
;
702 case AL_VOLUME_ENV_HOLDTIME_SOFT
:
703 self
->VolEnv
.HoldTime
= value
;
705 case AL_VOLUME_ENV_DECAYTIME_SOFT
:
706 self
->VolEnv
.DecayTime
= value
;
708 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
:
709 self
->VolEnv
.SustainAttn
= value
;
711 case AL_VOLUME_ENV_RELEASETIME_SOFT
:
712 self
->VolEnv
.ReleaseTime
= value
;
714 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
:
715 self
->VolEnv
.KeyToHoldTime
= value
;
717 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
:
718 self
->VolEnv
.KeyToDecayTime
= value
;
721 case AL_ATTENUATION_SOFT
:
723 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
724 self
->Attenuation
= value
;
727 case AL_TUNING_COARSE_SOFT
:
728 self
->CoarseTuning
= value
;
730 case AL_TUNING_FINE_SOFT
:
731 self
->FineTuning
= value
;
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
;
741 case AL_TUNING_SCALE_SOFT
:
742 self
->TuningScale
= value
;
745 case AL_EXCLUSIVE_CLASS_SOFT
:
746 self
->ExclusiveClass
= value
;
749 case AL_SAMPLE_START_SOFT
:
753 case AL_SAMPLE_END_SOFT
:
757 case AL_SAMPLE_LOOP_START_SOFT
:
758 self
->LoopStart
= value
;
761 case AL_SAMPLE_LOOP_END_SOFT
:
762 self
->LoopEnd
= value
;
765 case AL_SAMPLE_RATE_SOFT
:
767 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
768 self
->SampleRate
= value
;
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
;
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
;
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
;
789 case AL_FONTSOUND_LINK_SOFT
:
794 link
= LookupFontsound(context
->Device
, value
);
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
);
804 SET_ERROR_AND_RETURN(context
, AL_INVALID_ENUM
);
808 static ALsfmodulator
*ALfontsound_getModStage(ALfontsound
*self
, ALsizei stage
)
810 ALsfmodulator
*ret
= LookupModulator(self
, stage
);
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
}
821 ret
= malloc(sizeof(*ret
));
823 InsertUIntMapEntry(&self
->ModulatorMap
, stage
, ret
);
828 void ALfontsound_setModStagei(ALfontsound
*self
, ALCcontext
*context
, ALsizei stage
, ALenum param
, ALint value
)
832 if(ReadRef(&self
->ref
) != 0)
833 SET_ERROR_AND_RETURN(context
, AL_INVALID_OPERATION
);
836 case AL_SOURCE1_INPUT_SOFT
:
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
;
852 case AL_SOURCE1_TYPE_SOFT
:
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
;
862 case AL_SOURCE1_FORM_SOFT
:
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
;
873 ALfontsound_getModStage(self
, stage
)->Amount
= value
;
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
;
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
;
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
);
916 case AL_SOURCE1_INPUT_SOFT
:
919 case AL_SOURCE0_INPUT_SOFT
:
920 values
[0] = mod
? mod
->Source
[srcidx
].Input
: AL_ONE_SOFT
;
923 case AL_SOURCE1_TYPE_SOFT
:
926 case AL_SOURCE0_TYPE_SOFT
:
927 values
[0] = mod
? mod
->Source
[srcidx
].Type
: AL_UNORM_SOFT
;
930 case AL_SOURCE1_FORM_SOFT
:
933 case AL_SOURCE0_FORM_SOFT
:
934 values
[0] = mod
? mod
->Source
[srcidx
].Form
: AL_LINEAR_SOFT
;
938 values
[0] = mod
? mod
->Amount
: 0;
941 case AL_TRANSFORM_OP_SOFT
:
942 values
[0] = mod
? mod
->TransformOp
: AL_LINEAR_SOFT
;
945 case AL_DESTINATION_SOFT
:
946 values
[0] = mod
? mod
->Dest
: AL_NONE
;
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
)
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
));