diff options
Diffstat (limited to 'OpenAL32/alMidi.c')
-rw-r--r-- | OpenAL32/alMidi.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c index d1231fa7..74e37267 100644 --- a/OpenAL32/alMidi.c +++ b/OpenAL32/alMidi.c @@ -7,7 +7,9 @@ #include <limits.h> #include "alMain.h" +#include "alMidi.h" #include "alError.h" +#include "alThunk.h" #include "evtqueue.h" #include "rwlock.h" #include "alu.h" @@ -23,6 +25,97 @@ MidiSynth *SynthCreate(ALCdevice *device) } +extern inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id); +extern inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id); + + +AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALsoundfont *sfont = calloc(1, sizeof(ALsoundfont)); + if(!sfont) + { + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + ALsoundfont_Construct(sfont); + + err = NewThunkEntry(&sfont->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->SfontMap, sfont->id, sfont); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(sfont->id); + memset(sfont, 0, sizeof(ALsoundfont)); + free(sfont); + + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, err, done); + } + + ids[cur] = sfont->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + if(!ids[i]) + continue; + + /* Check for valid soundfont ID */ + if((sfont=LookupSfont(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sfont->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if((sfont=RemoveSfont(device, ids[i])) == NULL) + continue; + FreeThunkEntry(sfont->id); + + ALsoundfont_Destruct(sfont); + + memset(sfont, 0, sizeof(*sfont)); + free(sfont); + } + +done: + ALCcontext_DecRef(context); +} + + AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(const char *filename) { ALCdevice *device; |