Add methods to get and set a preset object's preset and bank numbers
[openal-soft.git] / OpenAL32 / alPreset.c
blobc01f4e802a08134360d6d173f8454fe5130a0419
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);
19 AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids)
21 ALCdevice *device;
22 ALCcontext *context;
23 ALsizei cur = 0;
24 ALenum err;
26 context = GetContextRef();
27 if(!context) return;
29 if(!(n >= 0))
30 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
32 device = context->Device;
33 for(cur = 0;cur < n;cur++)
35 ALsfpreset *preset = calloc(1, sizeof(ALsfpreset));
36 if(!preset)
38 alDeletePresetsSOFT(cur, ids);
39 SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
41 ALsfpreset_Construct(preset);
43 err = NewThunkEntry(&preset->id);
44 if(err == AL_NO_ERROR)
45 err = InsertUIntMapEntry(&device->PresetMap, preset->id, preset);
46 if(err != AL_NO_ERROR)
48 ALsfpreset_Destruct(preset);
49 memset(preset, 0, sizeof(*preset));
50 free(preset);
52 alDeletePresetsSOFT(cur, ids);
53 SET_ERROR_AND_GOTO(context, err, done);
56 ids[cur] = preset->id;
59 done:
60 ALCcontext_DecRef(context);
63 AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids)
65 ALCdevice *device;
66 ALCcontext *context;
67 ALsfpreset *preset;
68 ALsizei i;
70 context = GetContextRef();
71 if(!context) return;
73 if(!(n >= 0))
74 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
76 device = context->Device;
77 for(i = 0;i < n;i++)
79 if(!ids[i])
80 continue;
82 /* Check for valid ID */
83 if((preset=LookupPreset(device, ids[i])) == NULL)
84 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
85 if(preset->ref != 0)
86 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
89 for(i = 0;i < n;i++)
91 if((preset=RemovePreset(device, ids[i])) == NULL)
92 continue;
94 ALsfpreset_Destruct(preset);
96 memset(preset, 0, sizeof(*preset));
97 free(preset);
100 done:
101 ALCcontext_DecRef(context);
104 AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id)
106 ALCcontext *context;
107 ALboolean ret;
109 context = GetContextRef();
110 if(!context) return AL_FALSE;
112 ret = ((!id || LookupPreset(context->Device, id)) ?
113 AL_TRUE : AL_FALSE);
115 ALCcontext_DecRef(context);
117 return ret;
120 AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value)
122 ALCdevice *device;
123 ALCcontext *context;
124 ALsfpreset *preset;
126 context = GetContextRef();
127 if(!context) return;
129 device = context->Device;
130 if((preset=LookupPreset(device, id)) == NULL)
131 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
132 if(preset->ref != 0)
133 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
134 switch(param)
136 case AL_MIDI_PRESET_SOFT:
137 if(!(value >= 0 && value <= 127))
138 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
139 preset->Preset = value;
140 break;
142 case AL_MIDI_BANK_SOFT:
143 if(!(value >= 0 && value <= 128))
144 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
145 preset->Bank = value;
146 break;
148 default:
149 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
152 done:
153 ALCcontext_DecRef(context);
156 AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values)
158 ALCdevice *device;
159 ALCcontext *context;
160 ALsfpreset *preset;
162 switch(param)
164 case AL_MIDI_PRESET_SOFT:
165 case AL_MIDI_BANK_SOFT:
166 alPresetiSOFT(id, param, values[0]);
167 return;
170 context = GetContextRef();
171 if(!context) return;
173 device = context->Device;
174 if((preset=LookupPreset(device, id)) == NULL)
175 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
176 if(preset->ref != 0)
177 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
178 switch(param)
180 default:
181 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
184 done:
185 ALCcontext_DecRef(context);
188 AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values)
190 ALCdevice *device;
191 ALCcontext *context;
192 ALsfpreset *preset;
194 context = GetContextRef();
195 if(!context) return;
197 device = context->Device;
198 if((preset=LookupPreset(device, id)) == NULL)
199 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
200 if(preset->ref != 0)
201 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
202 switch(param)
204 case AL_MIDI_PRESET_SOFT:
205 values[0] = preset->Preset;
206 break;
208 case AL_MIDI_BANK_SOFT:
209 values[0] = preset->Bank;
210 break;
212 default:
213 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
216 done:
217 ALCcontext_DecRef(context);
221 /* ReleaseALPresets
223 * Called to destroy any presets that still exist on the device
225 void ReleaseALPresets(ALCdevice *device)
227 ALsizei i;
228 for(i = 0;i < device->PresetMap.size;i++)
230 ALsfpreset *temp = device->PresetMap.array[i].value;
231 device->PresetMap.array[i].value = NULL;
233 ALsfpreset_Destruct(temp);
235 memset(temp, 0, sizeof(*temp));
236 free(temp);