aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2014-01-04 05:30:57 -0800
committerChris Robinson <[email protected]>2014-01-04 05:30:57 -0800
commit540a99e71fa4ce3de8049656629861aa0a7e5568 (patch)
tree34651c72d9c31bb5a86f9506bfc301d84897c239
parentbb54743425c92856347c8c3f04ac07e319ff0fcd (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.c49
-rw-r--r--Alc/midi/base.c49
-rw-r--r--Alc/midi/base.h1
-rw-r--r--OpenAL32/alSoundfont.c22
4 files changed, 68 insertions, 53 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 97ac04bb..28e1efcb 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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);