diff options
author | Chris Robinson <[email protected]> | 2014-01-04 05:30:57 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-01-04 05:30:57 -0800 |
commit | 540a99e71fa4ce3de8049656629861aa0a7e5568 (patch) | |
tree | 34651c72d9c31bb5a86f9506bfc301d84897c239 | |
parent | bb54743425c92856347c8c3f04ac07e319ff0fcd (diff) |
Allow "deleting" the default soundfont
The ID remains valid and the soundfont will be reloaded as needed, but this
provides a way for the application to clear up the soundfont memory.
-rw-r--r-- | Alc/ALc.c | 49 | ||||
-rw-r--r-- | Alc/midi/base.c | 49 | ||||
-rw-r--r-- | Alc/midi/base.h | 1 | ||||
-rw-r--r-- | OpenAL32/alSoundfont.c | 22 |
4 files changed, 68 insertions, 53 deletions
@@ -1950,54 +1950,7 @@ static ALCvoid FreeDevice(ALCdevice *device) } if(device->DefaultSfont) - { - ALsoundfont *sfont = device->DefaultSfont; - ALsfpreset **presets; - ALsizei num_presets; - ALsizei i; - - presets = ExchangePtr((XchgPtr*)&sfont->Presets, NULL); - num_presets = ExchangeInt(&sfont->NumPresets, 0); - - for(i = 0;i < num_presets;i++) - { - ALsfpreset *preset = presets[i]; - ALfontsound **sounds; - ALsizei num_sounds; - ALboolean deleting; - ALsizei j; - - sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL); - num_sounds = ExchangeInt(&preset->NumSounds, 0); - DeletePreset(preset, device); - preset = NULL; - - for(j = 0;j < num_sounds;j++) - DecrementRef(&sounds[j]->ref); - /* Some fontsounds may not be immediately deletable because they're - * linked to another fontsound. When those fontsounds are deleted - * they should become deletable, so use a loop until all fontsounds - * are deleted. */ - do { - deleting = AL_FALSE; - for(j = 0;j < num_sounds;j++) - { - if(sounds[j] && sounds[j]->ref == 0) - { - deleting = AL_TRUE; - RemoveFontsound(device, sounds[j]->id); - ALfontsound_Destruct(sounds[j]); - free(sounds[j]); - sounds[j] = NULL; - } - } - } while(deleting); - free(sounds); - } - - ALsoundfont_Destruct(sfont); - free(sfont); - } + MidiSynth_deleteSoundfont(device, device->DefaultSfont); device->DefaultSfont = NULL; if(device->BufferMap.size > 0) diff --git a/Alc/midi/base.c b/Alc/midi/base.c index 2ebb24e1..cf677841 100644 --- a/Alc/midi/base.c +++ b/Alc/midi/base.c @@ -188,6 +188,55 @@ ALsoundfont *MidiSynth_getDefSoundfont(ALCcontext *context) return device->DefaultSfont; } +void MidiSynth_deleteSoundfont(ALCdevice *device, ALsoundfont *sfont) +{ + ALsfpreset **presets; + ALsizei num_presets; + ALsizei i; + + presets = ExchangePtr((XchgPtr*)&sfont->Presets, NULL); + num_presets = ExchangeInt(&sfont->NumPresets, 0); + + for(i = 0;i < num_presets;i++) + { + ALsfpreset *preset = presets[i]; + ALfontsound **sounds; + ALsizei num_sounds; + ALboolean deleting; + ALsizei j; + + sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL); + num_sounds = ExchangeInt(&preset->NumSounds, 0); + DeletePreset(preset, device); + preset = NULL; + + for(j = 0;j < num_sounds;j++) + DecrementRef(&sounds[j]->ref); + /* Some fontsounds may not be immediately deletable because they're + * linked to another fontsound. When those fontsounds are deleted + * they should become deletable, so use a loop until all fontsounds + * are deleted. */ + do { + deleting = AL_FALSE; + for(j = 0;j < num_sounds;j++) + { + if(sounds[j] && sounds[j]->ref == 0) + { + deleting = AL_TRUE; + RemoveFontsound(device, sounds[j]->id); + ALfontsound_Destruct(sounds[j]); + free(sounds[j]); + sounds[j] = NULL; + } + } + } while(deleting); + free(sounds); + } + + ALsoundfont_Destruct(sfont); + free(sfont); +} + ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids) { ALCdevice *device = context->Device; diff --git a/Alc/midi/base.h b/Alc/midi/base.h index 72e83b7d..25bd35dd 100644 --- a/Alc/midi/base.h +++ b/Alc/midi/base.h @@ -53,6 +53,7 @@ typedef struct MidiSynth { void MidiSynth_Construct(MidiSynth *self, ALCdevice *device); void MidiSynth_Destruct(MidiSynth *self); struct ALsoundfont *MidiSynth_getDefSoundfont(ALCcontext *context); +void MidiSynth_deleteSoundfont(ALCdevice *device, struct ALsoundfont *sfont); ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain) { self->Gain = gain; } inline ALfloat MidiSynth_getGain(const MidiSynth *self) { return self->Gain; } diff --git a/OpenAL32/alSoundfont.c b/OpenAL32/alSoundfont.c index 60a18ea5..04b5e525 100644 --- a/OpenAL32/alSoundfont.c +++ b/OpenAL32/alSoundfont.c @@ -76,11 +76,13 @@ AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) 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) + if(ids[i] == 0) + { + if(!(sfont=device->DefaultSfont)) + continue; + } + else if((sfont=LookupSfont(device, ids[i])) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(sfont->Mapped != AL_FALSE || sfont->ref != 0) SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); @@ -88,7 +90,17 @@ AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) for(i = 0;i < n;i++) { - if((sfont=RemoveSfont(device, ids[i])) == NULL) + if(ids[i] == 0) + { + MidiSynth *synth = device->Synth; + WriteLock(&synth->Lock); + if(device->DefaultSfont != NULL) + MidiSynth_deleteSoundfont(device, device->DefaultSfont); + device->DefaultSfont = NULL; + WriteUnlock(&synth->Lock); + continue; + } + else if((sfont=RemoveSfont(device, ids[i])) == NULL) continue; ALsoundfont_Destruct(sfont); |