12 #include "midi/base.h"
15 extern inline struct ALsfpreset
*LookupPreset(ALCdevice
*device
, ALuint id
);
16 extern inline struct ALsfpreset
*RemovePreset(ALCdevice
*device
, ALuint id
);
18 static void ALsfpreset_Construct(ALsfpreset
*self
);
19 void ALsfpreset_Destruct(ALsfpreset
*self
);
22 AL_API
void AL_APIENTRY
alGenPresetsSOFT(ALsizei n
, ALuint
*ids
)
27 context
= GetContextRef();
31 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
33 for(cur
= 0;cur
< n
;cur
++)
35 ALsfpreset
*preset
= NewPreset(context
);
38 alDeletePresetsSOFT(cur
, ids
);
42 ids
[cur
] = preset
->id
;
46 ALCcontext_DecRef(context
);
49 AL_API ALvoid AL_APIENTRY
alDeletePresetsSOFT(ALsizei n
, const ALuint
*ids
)
56 context
= GetContextRef();
60 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
62 device
= context
->Device
;
65 /* Check for valid ID */
66 if((preset
=LookupPreset(device
, ids
[i
])) == NULL
)
67 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
68 if(ReadRef(&preset
->ref
) != 0)
69 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
74 if((preset
=LookupPreset(device
, ids
[i
])) == NULL
)
76 DeletePreset(preset
, device
);
80 ALCcontext_DecRef(context
);
83 AL_API ALboolean AL_APIENTRY
alIsPresetSOFT(ALuint id
)
88 context
= GetContextRef();
89 if(!context
) return AL_FALSE
;
91 ret
= LookupPreset(context
->Device
, id
) ? AL_TRUE
: AL_FALSE
;
93 ALCcontext_DecRef(context
);
98 AL_API
void AL_APIENTRY
alPresetiSOFT(ALuint id
, ALenum param
, ALint value
)
104 context
= GetContextRef();
107 device
= context
->Device
;
108 if((preset
=LookupPreset(device
, id
)) == NULL
)
109 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
110 if(ReadRef(&preset
->ref
) != 0)
111 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
114 case AL_MIDI_PRESET_SOFT
:
115 if(!(value
>= 0 && value
<= 127))
116 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
117 preset
->Preset
= value
;
120 case AL_MIDI_BANK_SOFT
:
121 if(!(value
>= 0 && value
<= 128))
122 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
123 preset
->Bank
= value
;
127 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
131 ALCcontext_DecRef(context
);
134 AL_API
void AL_APIENTRY
alPresetivSOFT(ALuint id
, ALenum param
, const ALint
*values
)
142 case AL_MIDI_PRESET_SOFT
:
143 case AL_MIDI_BANK_SOFT
:
144 alPresetiSOFT(id
, param
, values
[0]);
148 context
= GetContextRef();
151 device
= context
->Device
;
152 if((preset
=LookupPreset(device
, id
)) == NULL
)
153 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
154 if(ReadRef(&preset
->ref
) != 0)
155 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
159 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
163 ALCcontext_DecRef(context
);
166 AL_API
void AL_APIENTRY
alGetPresetivSOFT(ALuint id
, ALenum param
, ALint
*values
)
173 context
= GetContextRef();
176 device
= context
->Device
;
177 if((preset
=LookupPreset(device
, id
)) == NULL
)
178 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
181 case AL_MIDI_PRESET_SOFT
:
182 values
[0] = preset
->Preset
;
185 case AL_MIDI_BANK_SOFT
:
186 values
[0] = preset
->Bank
;
189 case AL_FONTSOUNDS_SIZE_SOFT
:
190 values
[0] = preset
->NumSounds
;
193 case AL_FONTSOUNDS_SOFT
:
194 for(i
= 0;i
< preset
->NumSounds
;i
++)
195 values
[i
] = preset
->Sounds
[i
]->id
;
199 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
203 ALCcontext_DecRef(context
);
206 AL_API
void AL_APIENTRY
alPresetFontsoundsSOFT(ALuint id
, ALsizei count
, const ALuint
*fsids
)
211 ALfontsound
**sounds
;
214 context
= GetContextRef();
217 device
= context
->Device
;
218 if(!(preset
=LookupPreset(device
, id
)))
219 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
221 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
223 if(ReadRef(&preset
->ref
) != 0)
224 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
230 sounds
= calloc(count
, sizeof(sounds
[0]));
232 SET_ERROR_AND_GOTO(context
, AL_OUT_OF_MEMORY
, done
);
234 for(i
= 0;i
< count
;i
++)
236 if(!(sounds
[i
]=LookupFontsound(device
, fsids
[i
])))
239 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
244 for(i
= 0;i
< count
;i
++)
245 IncrementRef(&sounds
[i
]->ref
);
247 sounds
= ExchangePtr((XchgPtr
*)&preset
->Sounds
, sounds
);
248 count
= ExchangeInt(&preset
->NumSounds
, count
);
250 for(i
= 0;i
< count
;i
++)
251 DecrementRef(&sounds
[i
]->ref
);
255 ALCcontext_DecRef(context
);
259 ALsfpreset
*NewPreset(ALCcontext
*context
)
261 ALCdevice
*device
= context
->Device
;
265 preset
= calloc(1, sizeof(*preset
));
267 SET_ERROR_AND_RETURN_VALUE(context
, AL_OUT_OF_MEMORY
, NULL
);
268 ALsfpreset_Construct(preset
);
270 err
= NewThunkEntry(&preset
->id
);
271 if(err
== AL_NO_ERROR
)
272 err
= InsertUIntMapEntry(&device
->PresetMap
, preset
->id
, preset
);
273 if(err
!= AL_NO_ERROR
)
275 ALsfpreset_Destruct(preset
);
276 memset(preset
, 0, sizeof(*preset
));
279 SET_ERROR_AND_RETURN_VALUE(context
, err
, NULL
);
285 void DeletePreset(ALsfpreset
*preset
, ALCdevice
*device
)
287 RemovePreset(device
, preset
->id
);
289 ALsfpreset_Destruct(preset
);
290 memset(preset
, 0, sizeof(*preset
));
295 static void ALsfpreset_Construct(ALsfpreset
*self
)
297 InitRef(&self
->ref
, 0);
308 void ALsfpreset_Destruct(ALsfpreset
*self
)
312 FreeThunkEntry(self
->id
);
315 for(i
= 0;i
< self
->NumSounds
;i
++)
316 DecrementRef(&self
->Sounds
[i
]->ref
);
325 * Called to destroy any presets that still exist on the device
327 void ReleaseALPresets(ALCdevice
*device
)
330 for(i
= 0;i
< device
->PresetMap
.size
;i
++)
332 ALsfpreset
*temp
= device
->PresetMap
.array
[i
].value
;
333 device
->PresetMap
.array
[i
].value
= NULL
;
335 ALsfpreset_Destruct(temp
);
337 memset(temp
, 0, sizeof(*temp
));