aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/ALc.c
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/ALc.c')
-rw-r--r--Alc/ALc.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 08fc2719..97ac04bb 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1949,6 +1949,57 @@ static ALCvoid FreeDevice(ALCdevice *device)
DELETE_OBJ(state);
}
+ 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);
+ }
+ device->DefaultSfont = NULL;
+
if(device->BufferMap.size > 0)
{
WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);