Multiply samples with the cubic coeffs before transposing
[openal-soft.git] / OpenAL32 / alPreset.c
blob1934ba059c41cd8c729311761fca7f726cdf10ca
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 ALsfpreset *LookupPreset(ALCdevice *device, ALuint id);
16 extern inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id);
18 static void ALsfpreset_Construct(ALsfpreset *self);
19 static void ALsfpreset_Destruct(ALsfpreset *self);
22 AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids)
24 ALCcontext *context;
25 ALsizei cur = 0;
27 context = GetContextRef();
28 if(!context) return;
30 if(!(n >= 0))
31 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
33 for(cur = 0;cur < n;cur++)
35 ALsfpreset *preset = NewPreset(context);
36 if(!preset)
38 alDeletePresetsSOFT(cur, ids);
39 break;
42 ids[cur] = preset->id;
45 done:
46 ALCcontext_DecRef(context);
49 AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids)
51 ALCdevice *device;
52 ALCcontext *context;
53 ALsfpreset *preset;
54 ALsizei i;
56 context = GetContextRef();
57 if(!context) return;
59 if(!(n >= 0))
60 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
62 device = context->Device;
63 for(i = 0;i < n;i++)
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);
72 for(i = 0;i < n;i++)
74 if((preset=LookupPreset(device, ids[i])) != NULL)
75 DeletePreset(device, preset);
78 done:
79 ALCcontext_DecRef(context);
82 AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id)
84 ALCcontext *context;
85 ALboolean ret;
87 context = GetContextRef();
88 if(!context) return AL_FALSE;
90 ret = LookupPreset(context->Device, id) ? AL_TRUE : AL_FALSE;
92 ALCcontext_DecRef(context);
94 return ret;
97 AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value)
99 ALCdevice *device;
100 ALCcontext *context;
101 ALsfpreset *preset;
103 context = GetContextRef();
104 if(!context) return;
106 device = context->Device;
107 if((preset=LookupPreset(device, id)) == NULL)
108 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
109 if(ReadRef(&preset->ref) != 0)
110 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
111 switch(param)
113 case AL_MIDI_PRESET_SOFT:
114 if(!(value >= 0 && value <= 127))
115 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
116 preset->Preset = value;
117 break;
119 case AL_MIDI_BANK_SOFT:
120 if(!(value >= 0 && value <= 128))
121 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
122 preset->Bank = value;
123 break;
125 default:
126 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
129 done:
130 ALCcontext_DecRef(context);
133 AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values)
135 ALCdevice *device;
136 ALCcontext *context;
137 ALsfpreset *preset;
139 switch(param)
141 case AL_MIDI_PRESET_SOFT:
142 case AL_MIDI_BANK_SOFT:
143 alPresetiSOFT(id, param, values[0]);
144 return;
147 context = GetContextRef();
148 if(!context) return;
150 device = context->Device;
151 if((preset=LookupPreset(device, id)) == NULL)
152 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
153 if(ReadRef(&preset->ref) != 0)
154 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
155 switch(param)
157 default:
158 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
161 done:
162 ALCcontext_DecRef(context);
165 AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values)
167 ALCdevice *device;
168 ALCcontext *context;
169 ALsfpreset *preset;
170 ALsizei i;
172 context = GetContextRef();
173 if(!context) return;
175 device = context->Device;
176 if((preset=LookupPreset(device, id)) == NULL)
177 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
178 switch(param)
180 case AL_MIDI_PRESET_SOFT:
181 values[0] = preset->Preset;
182 break;
184 case AL_MIDI_BANK_SOFT:
185 values[0] = preset->Bank;
186 break;
188 case AL_FONTSOUNDS_SIZE_SOFT:
189 values[0] = preset->NumSounds;
190 break;
192 case AL_FONTSOUNDS_SOFT:
193 for(i = 0;i < preset->NumSounds;i++)
194 values[i] = preset->Sounds[i]->id;
195 break;
197 default:
198 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
201 done:
202 ALCcontext_DecRef(context);
205 AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids)
207 ALCdevice *device;
208 ALCcontext *context;
209 ALsfpreset *preset;
210 ALfontsound **sounds;
211 ALsizei i;
213 context = GetContextRef();
214 if(!context) return;
216 device = context->Device;
217 if(!(preset=LookupPreset(device, id)))
218 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
219 if(count < 0)
220 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
222 if(ReadRef(&preset->ref) != 0)
223 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
225 if(count == 0)
226 sounds = NULL;
227 else
229 sounds = calloc(count, sizeof(sounds[0]));
230 if(!sounds)
231 SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
233 for(i = 0;i < count;i++)
235 if(!(sounds[i]=LookupFontsound(device, fsids[i])))
237 free(sounds);
238 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
243 for(i = 0;i < count;i++)
244 IncrementRef(&sounds[i]->ref);
246 sounds = ExchangePtr((XchgPtr*)&preset->Sounds, sounds);
247 count = ExchangeInt(&preset->NumSounds, count);
249 for(i = 0;i < count;i++)
250 DecrementRef(&sounds[i]->ref);
251 free(sounds);
253 done:
254 ALCcontext_DecRef(context);
258 ALsfpreset *NewPreset(ALCcontext *context)
260 ALCdevice *device = context->Device;
261 ALsfpreset *preset;
262 ALenum err;
264 preset = calloc(1, sizeof(*preset));
265 if(!preset)
266 SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL);
267 ALsfpreset_Construct(preset);
269 err = NewThunkEntry(&preset->id);
270 if(err == AL_NO_ERROR)
271 err = InsertUIntMapEntry(&device->PresetMap, preset->id, preset);
272 if(err != AL_NO_ERROR)
274 ALsfpreset_Destruct(preset);
275 memset(preset, 0, sizeof(*preset));
276 free(preset);
278 SET_ERROR_AND_RETURN_VALUE(context, err, NULL);
281 return preset;
284 void DeletePreset(ALCdevice *device, ALsfpreset *preset)
286 RemovePreset(device, preset->id);
288 ALsfpreset_Destruct(preset);
289 memset(preset, 0, sizeof(*preset));
290 free(preset);
294 static void ALsfpreset_Construct(ALsfpreset *self)
296 InitRef(&self->ref, 0);
298 self->Preset = 0;
299 self->Bank = 0;
301 self->Sounds = NULL;
302 self->NumSounds = 0;
304 self->id = 0;
307 static void ALsfpreset_Destruct(ALsfpreset *self)
309 ALsizei i;
311 FreeThunkEntry(self->id);
312 self->id = 0;
314 for(i = 0;i < self->NumSounds;i++)
315 DecrementRef(&self->Sounds[i]->ref);
316 free(self->Sounds);
317 self->Sounds = NULL;
318 self->NumSounds = 0;
322 /* ReleaseALPresets
324 * Called to destroy any presets that still exist on the device
326 void ReleaseALPresets(ALCdevice *device)
328 ALsizei i;
329 for(i = 0;i < device->PresetMap.size;i++)
331 ALsfpreset *temp = device->PresetMap.array[i].value;
332 device->PresetMap.array[i].value = NULL;
334 ALsfpreset_Destruct(temp);
336 memset(temp, 0, sizeof(*temp));
337 free(temp);