Hi all, I'm still having problems (with CVS HEAD) with memory not being freed. This seems to have been caused by still-active voices maintaining their lock on the sfont's refcount (see start of delete_fluid_defsfont() in src/fluid_defsfont.c).
The solution I've attached is to explicitly call fluid_voice_off() before trying to delete the sfont(s). This should be OK, right? For neatness, I've also updated fluid_voice.c so neither fluid_voice_off( NULL) nor calling fluid_voice_off() twice with the same voice crashes fluidsynth. I found a couple of other minor memory leaks: the string tokenizer usage in fluid_settings.c and a leaked FILE pointer in fluid_defsfont.c. Both should be fixed in the patch. With these changes, I'm now only seeing a leak of around 10kB or so. This all seems to come from libasound and libc, and (from what I can see) isn't fluidsynth's fault. I've tested the code against my simple test-case and it seems to work OK. But, I'm new to fluidsynth code; perhaps some more familiar with the code-base should review this patch. Cheers, Paul.
Index: src/fluid_defsfont.c
===================================================================
RCS file: /sources/fluid/fluidsynth/src/fluid_defsfont.c,v
retrieving revision 1.11
diff -u -r1.11 fluid_defsfont.c
--- src/fluid_defsfont.c 23 Nov 2006 18:49:36 -0000 1.11
+++ src/fluid_defsfont.c 28 Nov 2006 19:30:15 -0000
@@ -311,10 +311,10 @@
sfsample = (SFSample *) p->data;
sample = new_fluid_sample();
if (sample == NULL) {
- return FLUID_FAILED;
+ goto err_exit;
}
if (fluid_sample_import_sfont(sample, sfsample, sfont) != FLUID_OK) {
- return FLUID_FAILED;
+ goto err_exit;
}
fluid_defsfont_add_sample(sfont, sample);
fluid_voice_optimize_sample(sample);
@@ -327,10 +327,10 @@
sfpreset = (SFPreset *) p->data;
preset = new_fluid_defpreset(sfont);
if (preset == NULL) {
- return FLUID_FAILED;
+ goto err_exit;
}
if (fluid_defpreset_import_sfont(preset, sfpreset, sfont) != FLUID_OK) {
- return FLUID_FAILED;
+ goto err_exit;
}
fluid_defsfont_add_preset(sfont, preset);
p = fluid_list_next(p);
@@ -338,6 +338,10 @@
sfont_free_data(sfdata);
return FLUID_OK;
+
+ err_exit:
+ sfont_free_data( sfdata);
+ return FLUID_FAILED;
}
/* fluid_defsfont_add_sample
@@ -3027,6 +3031,9 @@
if (sf->fname)
free (sf->fname);
+ if( sf->sffd)
+ fclose( sf->sffd);
+
p = sf->info;
while (p)
{
Index: src/fluid_settings.c
===================================================================
RCS file: /sources/fluid/fluidsynth/src/fluid_settings.c,v
retrieving revision 1.2
diff -u -r1.2 fluid_settings.c
--- src/fluid_settings.c 23 Nov 2006 18:49:36 -0000 1.2
+++ src/fluid_settings.c 28 Nov 2006 19:30:15 -0000
@@ -32,6 +32,8 @@
static void fluid_settings_hash_delete(void* value, int type);
static int fluid_settings_tokenize(char* s, char* buf, char** ptr);
+static fluid_strtok_t* fluid_settings_strtok = NULL;
+
typedef struct {
char* value;
@@ -167,6 +169,11 @@
void delete_fluid_settings(fluid_settings_t* settings)
{
+ if( fluid_settings_strtok) {
+ delete_fluid_strtok( fluid_settings_strtok);
+ fluid_settings_strtok = NULL;
+ }
+
delete_fluid_hashtable(settings);
}
@@ -196,8 +203,6 @@
fluid_midi_driver_settings(settings);
}
-static fluid_strtok_t* fluid_settings_strtok = NULL;
-
int fluid_settings_tokenize(char* s, char* buf, char** ptr)
{
int n = 0;
@@ -214,6 +219,7 @@
ptr[n++] = fluid_strtok_next_token(fluid_settings_strtok);
}
+
return n;
}
Index: src/fluid_synth.c
===================================================================
RCS file: /sources/fluid/fluidsynth/src/fluid_synth.c,v
retrieving revision 1.17
diff -u -r1.17 fluid_synth.c
--- src/fluid_synth.c 23 Nov 2006 18:49:36 -0000 1.17
+++ src/fluid_synth.c 28 Nov 2006 19:30:15 -0000
@@ -601,6 +601,18 @@
synth->state = FLUID_SYNTH_STOPPED;
+ /* turn off all voices, needed to unload SoundFonts */
+ if (synth->voice != NULL) {
+ for (i = 0; i < synth->nvoice; i++) {
+
+ if( !synth->voice[i] ||!fluid_voice_is_playing( synth->voice[i]))
+ continue;
+
+ fluid_voice_off(synth->voice[i]);
+ }
+ }
+
+
/* delete all the SoundFonts */
for (list = synth->sfont; list; list = fluid_list_next(list)) {
sfont = (fluid_sfont_t*) fluid_list_get(list);
@@ -639,9 +651,7 @@
if (synth->voice != NULL) {
for (i = 0; i < synth->nvoice; i++) {
- if (synth->voice[i] != NULL) {
- delete_fluid_voice(synth->voice[i]);
- }
+ delete_fluid_voice(synth->voice[i]);
}
FLUID_FREE(synth->voice);
}
Index: src/fluid_voice.c
===================================================================
RCS file: /sources/fluid/fluidsynth/src/fluid_voice.c,v
retrieving revision 1.16
diff -u -r1.16 fluid_voice.c
--- src/fluid_voice.c 18 Feb 2006 23:46:34 -0000 1.16
+++ src/fluid_voice.c 28 Nov 2006 19:30:15 -0000
@@ -1708,6 +1708,10 @@
int
fluid_voice_off(fluid_voice_t* voice)
{
+ if( voice == NULL) {
+ return FLUID_OK;
+ }
+
fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
voice->chan = NO_CHANNEL;
@@ -1718,9 +1722,10 @@
voice->status = FLUID_VOICE_OFF;
/* Decrement the reference count of the sample. */
- fluid_sample_decr_ref(voice->sample);
-
- voice->sample = NULL;
+ if( voice->sample) {
+ fluid_sample_decr_ref(voice->sample);
+ voice->sample = NULL;
+ }
return FLUID_OK;
}
pgpdh6GAbrrIV.pgp
Description: PGP signature
_______________________________________________ fluid-dev mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/fluid-dev
