13 #include "midi/base.h"
16 extern inline struct ALfontsound
*LookupFontsound(ALCdevice
*device
, ALuint id
);
17 extern inline struct ALfontsound
*RemoveFontsound(ALCdevice
*device
, ALuint id
);
20 static void ALfontsound_Construct(ALfontsound
*self
);
21 static void ALfontsound_Destruct(ALfontsound
*self
);
22 void ALfontsound_setPropi(ALfontsound
*self
, ALCcontext
*context
, ALenum param
, ALint value
);
23 static ALsfmodulator
*ALfontsound_getModStage(ALfontsound
*self
, ALsizei stage
);
24 void ALfontsound_setModStagei(ALfontsound
*self
, ALCcontext
*context
, ALsizei stage
, ALenum param
, ALint value
);
25 static void ALfontsound_getModStagei(ALfontsound
*self
, ALCcontext
*context
, ALsizei stage
, ALenum param
, ALint
*values
);
27 static inline struct ALsfmodulator
*LookupModulator(ALfontsound
*sound
, ALuint id
)
29 ALsfmodulator
*mod
= LookupUIntMapKey(&sound
->ModulatorMap
, id
>>2);
35 AL_API
void AL_APIENTRY
alGenFontsoundsSOFT(ALsizei n
, ALuint
*ids
)
40 context
= GetContextRef();
44 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
46 for(cur
= 0;cur
< n
;cur
++)
48 ALfontsound
*sound
= NewFontsound(context
);
51 alDeleteFontsoundsSOFT(cur
, ids
);
59 ALCcontext_DecRef(context
);
62 AL_API ALvoid AL_APIENTRY
alDeleteFontsoundsSOFT(ALsizei n
, const ALuint
*ids
)
69 context
= GetContextRef();
73 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
75 device
= context
->Device
;
78 /* Check for valid ID */
79 if((inst
=LookupFontsound(device
, ids
[i
])) == NULL
)
80 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
81 if(ReadRef(&inst
->ref
) != 0)
82 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
87 if((inst
=LookupFontsound(device
, ids
[i
])) != NULL
)
88 DeleteFontsound(device
, inst
);
92 ALCcontext_DecRef(context
);
95 AL_API ALboolean AL_APIENTRY
alIsFontsoundSOFT(ALuint id
)
100 context
= GetContextRef();
101 if(!context
) return AL_FALSE
;
103 ret
= LookupFontsound(context
->Device
, id
) ? AL_TRUE
: AL_FALSE
;
105 ALCcontext_DecRef(context
);
110 AL_API
void AL_APIENTRY
alFontsoundiSOFT(ALuint id
, ALenum param
, ALint value
)
116 context
= GetContextRef();
119 device
= context
->Device
;
120 if(!(sound
=LookupFontsound(device
, id
)))
121 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
122 if(ReadRef(&sound
->ref
) != 0)
123 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
125 ALfontsound_setPropi(sound
, context
, param
, value
);
128 ALCcontext_DecRef(context
);
131 AL_API
void AL_APIENTRY
alFontsound2iSOFT(ALuint id
, ALenum param
, ALint value1
, ALint value2
)
137 context
= GetContextRef();
140 device
= context
->Device
;
141 if(!(sound
=LookupFontsound(device
, id
)))
142 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
143 if(ReadRef(&sound
->ref
) != 0)
144 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
147 case AL_KEY_RANGE_SOFT
:
148 if(!(value1
>= 0 && value1
<= 127 && value2
>= 0 && value2
<= 127 && value2
>= value1
))
149 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
150 sound
->MinKey
= value1
;
151 sound
->MaxKey
= value2
;
154 case AL_VELOCITY_RANGE_SOFT
:
155 if(!(value1
>= 0 && value1
<= 127 && value2
>= 0 && value2
<= 127 && value2
>= value1
))
156 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
157 sound
->MinVelocity
= value1
;
158 sound
->MaxVelocity
= value2
;
162 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
166 ALCcontext_DecRef(context
);
169 AL_API
void AL_APIENTRY
alFontsoundivSOFT(ALuint id
, ALenum param
, const ALint
*values
)
177 case AL_KEY_RANGE_SOFT
:
178 case AL_VELOCITY_RANGE_SOFT
:
179 alFontsound2iSOFT(id
, param
, values
[0], values
[1]);
182 case AL_MOD_LFO_TO_PITCH_SOFT
:
183 case AL_VIBRATO_LFO_TO_PITCH_SOFT
:
184 case AL_MOD_ENV_TO_PITCH_SOFT
:
185 case AL_FILTER_CUTOFF_SOFT
:
186 case AL_FILTER_RESONANCE_SOFT
:
187 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
:
188 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
:
189 case AL_MOD_LFO_TO_VOLUME_SOFT
:
190 case AL_CHORUS_SEND_SOFT
:
191 case AL_REVERB_SEND_SOFT
:
193 case AL_MOD_LFO_DELAY_SOFT
:
194 case AL_MOD_LFO_FREQUENCY_SOFT
:
195 case AL_VIBRATO_LFO_DELAY_SOFT
:
196 case AL_VIBRATO_LFO_FREQUENCY_SOFT
:
197 case AL_MOD_ENV_DELAYTIME_SOFT
:
198 case AL_MOD_ENV_ATTACKTIME_SOFT
:
199 case AL_MOD_ENV_HOLDTIME_SOFT
:
200 case AL_MOD_ENV_DECAYTIME_SOFT
:
201 case AL_MOD_ENV_SUSTAINVOLUME_SOFT
:
202 case AL_MOD_ENV_RELEASETIME_SOFT
:
203 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
:
204 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
:
205 case AL_VOLUME_ENV_DELAYTIME_SOFT
:
206 case AL_VOLUME_ENV_ATTACKTIME_SOFT
:
207 case AL_VOLUME_ENV_HOLDTIME_SOFT
:
208 case AL_VOLUME_ENV_DECAYTIME_SOFT
:
209 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
:
210 case AL_VOLUME_ENV_RELEASETIME_SOFT
:
211 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
:
212 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
:
213 case AL_ATTENUATION_SOFT
:
214 case AL_TUNING_COARSE_SOFT
:
215 case AL_TUNING_FINE_SOFT
:
216 case AL_LOOP_MODE_SOFT
:
217 case AL_TUNING_SCALE_SOFT
:
218 case AL_EXCLUSIVE_CLASS_SOFT
:
219 case AL_SAMPLE_START_SOFT
:
220 case AL_SAMPLE_END_SOFT
:
221 case AL_SAMPLE_LOOP_START_SOFT
:
222 case AL_SAMPLE_LOOP_END_SOFT
:
223 case AL_SAMPLE_RATE_SOFT
:
224 case AL_BASE_KEY_SOFT
:
225 case AL_KEY_CORRECTION_SOFT
:
226 case AL_SAMPLE_TYPE_SOFT
:
227 case AL_FONTSOUND_LINK_SOFT
:
228 alFontsoundiSOFT(id
, param
, values
[0]);
232 context
= GetContextRef();
235 device
= context
->Device
;
236 if(!(sound
=LookupFontsound(device
, id
)))
237 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
238 if(ReadRef(&sound
->ref
) != 0)
239 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
243 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
247 ALCcontext_DecRef(context
);
250 AL_API
void AL_APIENTRY
alGetFontsoundivSOFT(ALuint id
, ALenum param
, ALint
*values
)
254 const ALfontsound
*sound
;
258 context
= GetContextRef();
261 device
= context
->Device
;
262 if(!(sound
=LookupFontsound(device
, id
)))
263 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
267 buffer
= ATOMIC_LOAD(&sound
->Buffer
);
268 values
[0] = (buffer
? buffer
->id
: 0);
271 case AL_MOD_LFO_TO_PITCH_SOFT
:
272 values
[0] = sound
->ModLfoToPitch
;
275 case AL_VIBRATO_LFO_TO_PITCH_SOFT
:
276 values
[0] = sound
->VibratoLfoToPitch
;
279 case AL_MOD_ENV_TO_PITCH_SOFT
:
280 values
[0] = sound
->ModEnvToPitch
;
283 case AL_FILTER_CUTOFF_SOFT
:
284 values
[0] = sound
->FilterCutoff
;
287 case AL_FILTER_RESONANCE_SOFT
:
288 values
[0] = sound
->FilterQ
;
291 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
:
292 values
[0] = sound
->ModLfoToFilterCutoff
;
295 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
:
296 values
[0] = sound
->ModEnvToFilterCutoff
;
299 case AL_MOD_LFO_TO_VOLUME_SOFT
:
300 values
[0] = sound
->ModLfoToVolume
;
303 case AL_CHORUS_SEND_SOFT
:
304 values
[0] = sound
->ChorusSend
;
307 case AL_REVERB_SEND_SOFT
:
308 values
[0] = sound
->ReverbSend
;
312 values
[0] = sound
->Pan
;
315 case AL_MOD_LFO_DELAY_SOFT
:
316 values
[0] = sound
->ModLfo
.Delay
;
318 case AL_MOD_LFO_FREQUENCY_SOFT
:
319 values
[0] = sound
->ModLfo
.Frequency
;
322 case AL_VIBRATO_LFO_DELAY_SOFT
:
323 values
[0] = sound
->VibratoLfo
.Delay
;
325 case AL_VIBRATO_LFO_FREQUENCY_SOFT
:
326 values
[0] = sound
->VibratoLfo
.Frequency
;
329 case AL_MOD_ENV_DELAYTIME_SOFT
:
330 values
[0] = sound
->ModEnv
.DelayTime
;
332 case AL_MOD_ENV_ATTACKTIME_SOFT
:
333 values
[0] = sound
->ModEnv
.AttackTime
;
335 case AL_MOD_ENV_HOLDTIME_SOFT
:
336 values
[0] = sound
->ModEnv
.HoldTime
;
338 case AL_MOD_ENV_DECAYTIME_SOFT
:
339 values
[0] = sound
->ModEnv
.DecayTime
;
341 case AL_MOD_ENV_SUSTAINVOLUME_SOFT
:
342 values
[0] = sound
->ModEnv
.SustainAttn
;
344 case AL_MOD_ENV_RELEASETIME_SOFT
:
345 values
[0] = sound
->ModEnv
.ReleaseTime
;
347 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
:
348 values
[0] = sound
->ModEnv
.KeyToHoldTime
;
350 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
:
351 values
[0] = sound
->ModEnv
.KeyToDecayTime
;
354 case AL_VOLUME_ENV_DELAYTIME_SOFT
:
355 values
[0] = sound
->VolEnv
.DelayTime
;
357 case AL_VOLUME_ENV_ATTACKTIME_SOFT
:
358 values
[0] = sound
->VolEnv
.AttackTime
;
360 case AL_VOLUME_ENV_HOLDTIME_SOFT
:
361 values
[0] = sound
->VolEnv
.HoldTime
;
363 case AL_VOLUME_ENV_DECAYTIME_SOFT
:
364 values
[0] = sound
->VolEnv
.DecayTime
;
366 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
:
367 values
[0] = sound
->VolEnv
.SustainAttn
;
369 case AL_VOLUME_ENV_RELEASETIME_SOFT
:
370 values
[0] = sound
->VolEnv
.ReleaseTime
;
372 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
:
373 values
[0] = sound
->VolEnv
.KeyToHoldTime
;
375 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
:
376 values
[0] = sound
->VolEnv
.KeyToDecayTime
;
379 case AL_KEY_RANGE_SOFT
:
380 values
[0] = sound
->MinKey
;
381 values
[1] = sound
->MaxKey
;
384 case AL_VELOCITY_RANGE_SOFT
:
385 values
[0] = sound
->MinVelocity
;
386 values
[1] = sound
->MaxVelocity
;
389 case AL_ATTENUATION_SOFT
:
390 values
[0] = sound
->Attenuation
;
393 case AL_TUNING_COARSE_SOFT
:
394 values
[0] = sound
->CoarseTuning
;
396 case AL_TUNING_FINE_SOFT
:
397 values
[0] = sound
->FineTuning
;
400 case AL_LOOP_MODE_SOFT
:
401 values
[0] = sound
->LoopMode
;
404 case AL_TUNING_SCALE_SOFT
:
405 values
[0] = sound
->TuningScale
;
408 case AL_EXCLUSIVE_CLASS_SOFT
:
409 values
[0] = sound
->ExclusiveClass
;
412 case AL_SAMPLE_START_SOFT
:
413 values
[0] = sound
->Start
;
416 case AL_SAMPLE_END_SOFT
:
417 values
[0] = sound
->End
;
420 case AL_SAMPLE_LOOP_START_SOFT
:
421 values
[0] = sound
->LoopStart
;
424 case AL_SAMPLE_LOOP_END_SOFT
:
425 values
[0] = sound
->LoopEnd
;
428 case AL_SAMPLE_RATE_SOFT
:
429 values
[0] = sound
->SampleRate
;
432 case AL_BASE_KEY_SOFT
:
433 values
[0] = sound
->PitchKey
;
436 case AL_KEY_CORRECTION_SOFT
:
437 values
[0] = sound
->PitchCorrection
;
440 case AL_SAMPLE_TYPE_SOFT
:
441 values
[0] = sound
->SampleType
;
444 case AL_FONTSOUND_LINK_SOFT
:
445 link
= ATOMIC_LOAD(&sound
->Link
);
446 values
[0] = (link
? link
->id
: 0);
450 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
454 ALCcontext_DecRef(context
);
457 AL_API
void AL_APIENTRY
alFontsoundModulatoriSOFT(ALuint id
, ALsizei stage
, ALenum param
, ALint value
)
463 context
= GetContextRef();
466 device
= context
->Device
;
467 if(!(sound
=LookupFontsound(device
, id
)))
468 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
469 ALfontsound_setModStagei(sound
, context
, stage
, param
, value
);
472 ALCcontext_DecRef(context
);
475 AL_API
void AL_APIENTRY
alGetFontsoundModulatorivSOFT(ALuint id
, ALsizei stage
, ALenum param
, ALint
*values
)
481 context
= GetContextRef();
484 device
= context
->Device
;
485 if(!(sound
=LookupFontsound(device
, id
)))
486 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
487 ALfontsound_getModStagei(sound
, context
, stage
, param
, values
);
490 ALCcontext_DecRef(context
);
494 ALfontsound
*NewFontsound(ALCcontext
*context
)
496 ALCdevice
*device
= context
->Device
;
500 sound
= calloc(1, sizeof(*sound
));
502 SET_ERROR_AND_RETURN_VALUE(context
, AL_OUT_OF_MEMORY
, NULL
);
503 ALfontsound_Construct(sound
);
505 err
= NewThunkEntry(&sound
->id
);
506 if(err
== AL_NO_ERROR
)
507 err
= InsertUIntMapEntry(&device
->FontsoundMap
, sound
->id
, sound
);
508 if(err
!= AL_NO_ERROR
)
510 ALfontsound_Destruct(sound
);
511 memset(sound
, 0, sizeof(*sound
));
514 SET_ERROR_AND_RETURN_VALUE(context
, err
, NULL
);
520 void DeleteFontsound(ALCdevice
*device
, ALfontsound
*sound
)
522 RemoveFontsound(device
, sound
->id
);
524 ALfontsound_Destruct(sound
);
526 memset(sound
, 0, sizeof(*sound
));
531 static void ALfontsound_Construct(ALfontsound
*self
)
533 InitRef(&self
->ref
, 0);
535 ATOMIC_INIT(&self
->Buffer
, NULL
);
539 self
->MinVelocity
= 0;
540 self
->MaxVelocity
= 127;
542 self
->ModLfoToPitch
= 0;
543 self
->VibratoLfoToPitch
= 0;
544 self
->ModEnvToPitch
= 0;
546 self
->FilterCutoff
= 13500;
548 self
->ModLfoToFilterCutoff
= 0;
549 self
->ModEnvToFilterCutoff
= 0;
550 self
->ModLfoToVolume
= 0;
552 self
->ChorusSend
= 0;
553 self
->ReverbSend
= 0;
557 self
->ModLfo
.Delay
= 0;
558 self
->ModLfo
.Frequency
= 0;
560 self
->VibratoLfo
.Delay
= 0;
561 self
->VibratoLfo
.Frequency
= 0;
563 self
->ModEnv
.DelayTime
= -12000;
564 self
->ModEnv
.AttackTime
= -12000;
565 self
->ModEnv
.HoldTime
= -12000;
566 self
->ModEnv
.DecayTime
= -12000;
567 self
->ModEnv
.SustainAttn
= 0;
568 self
->ModEnv
.ReleaseTime
= -12000;
569 self
->ModEnv
.KeyToHoldTime
= 0;
570 self
->ModEnv
.KeyToDecayTime
= 0;
572 self
->VolEnv
.DelayTime
= -12000;
573 self
->VolEnv
.AttackTime
= -12000;
574 self
->VolEnv
.HoldTime
= -12000;
575 self
->VolEnv
.DecayTime
= -12000;
576 self
->VolEnv
.SustainAttn
= 0;
577 self
->VolEnv
.ReleaseTime
= -12000;
578 self
->VolEnv
.KeyToHoldTime
= 0;
579 self
->VolEnv
.KeyToDecayTime
= 0;
581 self
->Attenuation
= 0;
583 self
->CoarseTuning
= 0;
584 self
->FineTuning
= 0;
586 self
->LoopMode
= AL_NONE
;
588 self
->TuningScale
= 100;
590 self
->ExclusiveClass
= 0;
596 self
->SampleRate
= 0;
598 self
->PitchCorrection
= 0;
599 self
->SampleType
= AL_MONO_SOFT
;
601 ATOMIC_INIT(&self
->Link
, NULL
);
603 InitUIntMap(&self
->ModulatorMap
, ~0);
608 static void ALfontsound_Destruct(ALfontsound
*self
)
614 FreeThunkEntry(self
->id
);
617 if((buffer
=ATOMIC_EXCHANGE(ALbuffer
*, &self
->Buffer
, NULL
)) != NULL
)
618 DecrementRef(&buffer
->ref
);
620 if((link
=ATOMIC_EXCHANGE(ALfontsound
*, &self
->Link
, NULL
)) != NULL
)
621 DecrementRef(&link
->ref
);
623 for(i
= 0;i
< self
->ModulatorMap
.size
;i
++)
625 free(self
->ModulatorMap
.array
[i
].value
);
626 self
->ModulatorMap
.array
[i
].value
= NULL
;
628 ResetUIntMap(&self
->ModulatorMap
);
631 void ALfontsound_setPropi(ALfontsound
*self
, ALCcontext
*context
, ALenum param
, ALint value
)
639 buffer
= value
? LookupBuffer(context
->Device
, value
) : NULL
;
641 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
644 /* Buffer must have a non-0 length, and must be mono. */
645 if(buffer
->SampleLen
<= 0 || buffer
->FmtChannels
!= FmtMono
)
646 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
649 if(buffer
) IncrementRef(&buffer
->ref
);
650 if((buffer
=ATOMIC_EXCHANGE(ALbuffer
*, &self
->Buffer
, buffer
)) != NULL
)
651 DecrementRef(&buffer
->ref
);
654 case AL_MOD_LFO_TO_PITCH_SOFT
:
655 self
->ModLfoToPitch
= value
;
658 case AL_VIBRATO_LFO_TO_PITCH_SOFT
:
659 self
->VibratoLfoToPitch
= value
;
662 case AL_MOD_ENV_TO_PITCH_SOFT
:
663 self
->ModEnvToPitch
= value
;
666 case AL_FILTER_CUTOFF_SOFT
:
667 self
->FilterCutoff
= value
;
670 case AL_FILTER_RESONANCE_SOFT
:
672 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
673 self
->FilterQ
= value
;
676 case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
:
677 self
->ModLfoToFilterCutoff
= value
;
680 case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
:
681 self
->ModEnvToFilterCutoff
= value
;
684 case AL_MOD_LFO_TO_VOLUME_SOFT
:
685 self
->ModLfoToVolume
= value
;
688 case AL_CHORUS_SEND_SOFT
:
689 if(!(value
>= 0 && value
<= 1000))
690 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
691 self
->ChorusSend
= value
;
693 case AL_REVERB_SEND_SOFT
:
694 if(!(value
>= 0 && value
<= 1000))
695 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
696 self
->ReverbSend
= value
;
703 case AL_MOD_LFO_DELAY_SOFT
:
704 self
->ModLfo
.Delay
= value
;
706 case AL_MOD_LFO_FREQUENCY_SOFT
:
707 self
->ModLfo
.Frequency
= value
;
710 case AL_VIBRATO_LFO_DELAY_SOFT
:
711 self
->VibratoLfo
.Delay
= value
;
713 case AL_VIBRATO_LFO_FREQUENCY_SOFT
:
714 self
->VibratoLfo
.Frequency
= value
;
717 case AL_MOD_ENV_DELAYTIME_SOFT
:
718 self
->ModEnv
.DelayTime
= value
;
720 case AL_MOD_ENV_ATTACKTIME_SOFT
:
721 self
->ModEnv
.AttackTime
= value
;
723 case AL_MOD_ENV_HOLDTIME_SOFT
:
724 self
->ModEnv
.HoldTime
= value
;
726 case AL_MOD_ENV_DECAYTIME_SOFT
:
727 self
->ModEnv
.DecayTime
= value
;
729 case AL_MOD_ENV_SUSTAINVOLUME_SOFT
:
730 self
->ModEnv
.SustainAttn
= value
;
732 case AL_MOD_ENV_RELEASETIME_SOFT
:
733 self
->ModEnv
.ReleaseTime
= value
;
735 case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
:
736 self
->ModEnv
.KeyToHoldTime
= value
;
738 case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
:
739 self
->ModEnv
.KeyToDecayTime
= value
;
742 case AL_VOLUME_ENV_DELAYTIME_SOFT
:
743 self
->VolEnv
.DelayTime
= value
;
745 case AL_VOLUME_ENV_ATTACKTIME_SOFT
:
746 self
->VolEnv
.AttackTime
= value
;
748 case AL_VOLUME_ENV_HOLDTIME_SOFT
:
749 self
->VolEnv
.HoldTime
= value
;
751 case AL_VOLUME_ENV_DECAYTIME_SOFT
:
752 self
->VolEnv
.DecayTime
= value
;
754 case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
:
755 self
->VolEnv
.SustainAttn
= value
;
757 case AL_VOLUME_ENV_RELEASETIME_SOFT
:
758 self
->VolEnv
.ReleaseTime
= value
;
760 case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
:
761 self
->VolEnv
.KeyToHoldTime
= value
;
763 case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
:
764 self
->VolEnv
.KeyToDecayTime
= value
;
767 case AL_ATTENUATION_SOFT
:
769 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
770 self
->Attenuation
= value
;
773 case AL_TUNING_COARSE_SOFT
:
774 self
->CoarseTuning
= value
;
776 case AL_TUNING_FINE_SOFT
:
777 self
->FineTuning
= value
;
780 case AL_LOOP_MODE_SOFT
:
781 if(!(value
== AL_NONE
|| value
== AL_LOOP_CONTINUOUS_SOFT
||
782 value
== AL_LOOP_UNTIL_RELEASE_SOFT
))
783 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
784 self
->LoopMode
= value
;
787 case AL_TUNING_SCALE_SOFT
:
788 self
->TuningScale
= value
;
791 case AL_EXCLUSIVE_CLASS_SOFT
:
792 self
->ExclusiveClass
= value
;
795 case AL_SAMPLE_START_SOFT
:
799 case AL_SAMPLE_END_SOFT
:
803 case AL_SAMPLE_LOOP_START_SOFT
:
804 self
->LoopStart
= value
;
807 case AL_SAMPLE_LOOP_END_SOFT
:
808 self
->LoopEnd
= value
;
811 case AL_SAMPLE_RATE_SOFT
:
813 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
814 self
->SampleRate
= value
;
817 case AL_BASE_KEY_SOFT
:
818 if(!((value
>= 0 && value
<= 127) || value
== 255))
819 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
820 self
->PitchKey
= value
;
823 case AL_KEY_CORRECTION_SOFT
:
824 if(!(value
>= -99 && value
<= 99))
825 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
826 self
->PitchCorrection
= value
;
829 case AL_SAMPLE_TYPE_SOFT
:
830 if(!(value
== AL_MONO_SOFT
|| value
== AL_RIGHT_SOFT
|| value
== AL_LEFT_SOFT
))
831 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
832 self
->SampleType
= value
;
835 case AL_FONTSOUND_LINK_SOFT
:
836 link
= value
? LookupFontsound(context
->Device
, value
) : NULL
;
838 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
840 if(link
) IncrementRef(&link
->ref
);
841 if((link
=ATOMIC_EXCHANGE(ALfontsound
*, &self
->Link
, link
)) != NULL
)
842 DecrementRef(&link
->ref
);
846 SET_ERROR_AND_RETURN(context
, AL_INVALID_ENUM
);
850 static ALsfmodulator
*ALfontsound_getModStage(ALfontsound
*self
, ALsizei stage
)
852 ALsfmodulator
*ret
= LookupModulator(self
, stage
);
855 static const ALsfmodulator moddef
= {
856 { { AL_ONE_SOFT
, AL_UNORM_SOFT
, AL_LINEAR_SOFT
},
857 { AL_ONE_SOFT
, AL_UNORM_SOFT
, AL_LINEAR_SOFT
} },
862 ret
= malloc(sizeof(ALsfmodulator
[4]));
867 InsertUIntMapEntry(&self
->ModulatorMap
, stage
>>2, ret
);
873 void ALfontsound_setModStagei(ALfontsound
*self
, ALCcontext
*context
, ALsizei stage
, ALenum param
, ALint value
)
877 if(ReadRef(&self
->ref
) != 0)
878 SET_ERROR_AND_RETURN(context
, AL_INVALID_OPERATION
);
881 case AL_SOURCE1_INPUT_SOFT
:
884 case AL_SOURCE0_INPUT_SOFT
:
885 if(!(value
== AL_ONE_SOFT
|| value
== AL_NOTEON_VELOCITY_SOFT
||
886 value
== AL_NOTEON_KEY_SOFT
|| value
== AL_KEYPRESSURE_SOFT
||
887 value
== AL_CHANNELPRESSURE_SOFT
|| value
== AL_PITCHBEND_SOFT
||
888 value
== AL_PITCHBEND_SENSITIVITY_SOFT
||
889 IsValidCtrlInput(value
)))
890 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
891 ALfontsound_getModStage(self
, stage
)->Source
[srcidx
].Input
= value
;
894 case AL_SOURCE1_TYPE_SOFT
:
897 case AL_SOURCE0_TYPE_SOFT
:
898 if(!(value
== AL_UNORM_SOFT
|| value
== AL_UNORM_REV_SOFT
||
899 value
== AL_SNORM_SOFT
|| value
== AL_SNORM_REV_SOFT
))
900 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
901 ALfontsound_getModStage(self
, stage
)->Source
[srcidx
].Type
= value
;
904 case AL_SOURCE1_FORM_SOFT
:
907 case AL_SOURCE0_FORM_SOFT
:
908 if(!(value
== AL_LINEAR_SOFT
|| value
== AL_CONCAVE_SOFT
||
909 value
== AL_CONVEX_SOFT
|| value
== AL_SWITCH_SOFT
))
910 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
911 ALfontsound_getModStage(self
, stage
)->Source
[srcidx
].Form
= value
;
915 ALfontsound_getModStage(self
, stage
)->Amount
= value
;
918 case AL_TRANSFORM_OP_SOFT
:
919 if(!(value
== AL_LINEAR_SOFT
|| value
== AL_ABSOLUTE_SOFT
))
920 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
921 ALfontsound_getModStage(self
, stage
)->TransformOp
= value
;
924 case AL_DESTINATION_SOFT
:
925 if(!(value
== AL_MOD_LFO_TO_PITCH_SOFT
|| value
== AL_VIBRATO_LFO_TO_PITCH_SOFT
||
926 value
== AL_MOD_ENV_TO_PITCH_SOFT
|| value
== AL_FILTER_CUTOFF_SOFT
||
927 value
== AL_FILTER_RESONANCE_SOFT
|| value
== AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
||
928 value
== AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
|| value
== AL_MOD_LFO_TO_VOLUME_SOFT
||
929 value
== AL_CHORUS_SEND_SOFT
|| value
== AL_REVERB_SEND_SOFT
|| value
== AL_PAN_SOFT
||
930 value
== AL_MOD_LFO_DELAY_SOFT
|| value
== AL_MOD_LFO_FREQUENCY_SOFT
||
931 value
== AL_VIBRATO_LFO_DELAY_SOFT
|| value
== AL_VIBRATO_LFO_FREQUENCY_SOFT
||
932 value
== AL_MOD_ENV_DELAYTIME_SOFT
|| value
== AL_MOD_ENV_ATTACKTIME_SOFT
||
933 value
== AL_MOD_ENV_HOLDTIME_SOFT
|| value
== AL_MOD_ENV_DECAYTIME_SOFT
||
934 value
== AL_MOD_ENV_SUSTAINVOLUME_SOFT
|| value
== AL_MOD_ENV_RELEASETIME_SOFT
||
935 value
== AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
|| value
== AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
||
936 value
== AL_VOLUME_ENV_DELAYTIME_SOFT
|| value
== AL_VOLUME_ENV_ATTACKTIME_SOFT
||
937 value
== AL_VOLUME_ENV_HOLDTIME_SOFT
|| value
== AL_VOLUME_ENV_DECAYTIME_SOFT
||
938 value
== AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
|| value
== AL_VOLUME_ENV_RELEASETIME_SOFT
||
939 value
== AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
|| value
== AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
||
940 value
== AL_ATTENUATION_SOFT
|| value
== AL_TUNING_COARSE_SOFT
||
941 value
== AL_TUNING_FINE_SOFT
|| value
== AL_TUNING_SCALE_SOFT
))
942 SET_ERROR_AND_RETURN(context
, AL_INVALID_VALUE
);
943 ALfontsound_getModStage(self
, stage
)->Dest
= value
;
947 SET_ERROR_AND_RETURN(context
, AL_INVALID_ENUM
);
951 static void ALfontsound_getModStagei(ALfontsound
*self
, ALCcontext
*context
, ALsizei stage
, ALenum param
, ALint
*values
)
953 ALsfmodulator
*mod
= LookupModulator(self
, stage
);
958 case AL_SOURCE1_INPUT_SOFT
:
961 case AL_SOURCE0_INPUT_SOFT
:
962 values
[0] = mod
? mod
->Source
[srcidx
].Input
: AL_ONE_SOFT
;
965 case AL_SOURCE1_TYPE_SOFT
:
968 case AL_SOURCE0_TYPE_SOFT
:
969 values
[0] = mod
? mod
->Source
[srcidx
].Type
: AL_UNORM_SOFT
;
972 case AL_SOURCE1_FORM_SOFT
:
975 case AL_SOURCE0_FORM_SOFT
:
976 values
[0] = mod
? mod
->Source
[srcidx
].Form
: AL_LINEAR_SOFT
;
980 values
[0] = mod
? mod
->Amount
: 0;
983 case AL_TRANSFORM_OP_SOFT
:
984 values
[0] = mod
? mod
->TransformOp
: AL_LINEAR_SOFT
;
987 case AL_DESTINATION_SOFT
:
988 values
[0] = mod
? mod
->Dest
: AL_NONE
;
992 SET_ERROR_AND_RETURN(context
, AL_INVALID_ENUM
);
997 /* ReleaseALFontsounds
999 * Called to destroy any fontsounds that still exist on the device
1001 void ReleaseALFontsounds(ALCdevice
*device
)
1004 for(i
= 0;i
< device
->FontsoundMap
.size
;i
++)
1006 ALfontsound
*temp
= device
->FontsoundMap
.array
[i
].value
;
1007 device
->FontsoundMap
.array
[i
].value
= NULL
;
1009 ALfontsound_Destruct(temp
);
1011 memset(temp
, 0, sizeof(*temp
));