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
)
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
)
75 DeletePreset(device
, preset
);
79 ALCcontext_DecRef(context
);
82 AL_API ALboolean AL_APIENTRY
alIsPresetSOFT(ALuint id
)
87 context
= GetContextRef();
88 if(!context
) return AL_FALSE
;
90 ret
= LookupPreset(context
->Device
, id
) ? AL_TRUE
: AL_FALSE
;
92 ALCcontext_DecRef(context
);
97 AL_API
void AL_APIENTRY
alPresetiSOFT(ALuint id
, ALenum param
, ALint value
)
103 context
= GetContextRef();
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
);
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
;
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
;
126 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
130 ALCcontext_DecRef(context
);
133 AL_API
void AL_APIENTRY
alPresetivSOFT(ALuint id
, ALenum param
, const ALint
*values
)
141 case AL_MIDI_PRESET_SOFT
:
142 case AL_MIDI_BANK_SOFT
:
143 alPresetiSOFT(id
, param
, values
[0]);
147 context
= GetContextRef();
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
);
158 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
162 ALCcontext_DecRef(context
);
165 AL_API
void AL_APIENTRY
alGetPresetivSOFT(ALuint id
, ALenum param
, ALint
*values
)
172 context
= GetContextRef();
175 device
= context
->Device
;
176 if((preset
=LookupPreset(device
, id
)) == NULL
)
177 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
180 case AL_MIDI_PRESET_SOFT
:
181 values
[0] = preset
->Preset
;
184 case AL_MIDI_BANK_SOFT
:
185 values
[0] = preset
->Bank
;
188 case AL_FONTSOUNDS_SIZE_SOFT
:
189 values
[0] = preset
->NumSounds
;
192 case AL_FONTSOUNDS_SOFT
:
193 for(i
= 0;i
< preset
->NumSounds
;i
++)
194 values
[i
] = preset
->Sounds
[i
]->id
;
198 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
202 ALCcontext_DecRef(context
);
205 AL_API
void AL_APIENTRY
alPresetFontsoundsSOFT(ALuint id
, ALsizei count
, const ALuint
*fsids
)
210 ALfontsound
**sounds
;
213 context
= GetContextRef();
216 device
= context
->Device
;
217 if(!(preset
=LookupPreset(device
, id
)))
218 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
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
);
229 sounds
= calloc(count
, sizeof(sounds
[0]));
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
])))
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
);
254 ALCcontext_DecRef(context
);
258 ALsfpreset
*NewPreset(ALCcontext
*context
)
260 ALCdevice
*device
= context
->Device
;
264 preset
= calloc(1, sizeof(*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
));
278 SET_ERROR_AND_RETURN_VALUE(context
, err
, NULL
);
284 void DeletePreset(ALCdevice
*device
, ALsfpreset
*preset
)
286 RemovePreset(device
, preset
->id
);
288 ALsfpreset_Destruct(preset
);
289 memset(preset
, 0, sizeof(*preset
));
294 static void ALsfpreset_Construct(ALsfpreset
*self
)
296 InitRef(&self
->ref
, 0);
307 static void ALsfpreset_Destruct(ALsfpreset
*self
)
311 FreeThunkEntry(self
->id
);
314 for(i
= 0;i
< self
->NumSounds
;i
++)
315 DecrementRef(&self
->Sounds
[i
]->ref
);
324 * Called to destroy any presets that still exist on the device
326 void ReleaseALPresets(ALCdevice
*device
)
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
));