Maybe ALSA CPU consumption problem is now fixed, more changes to ALSA

sequencer driver, many many memory leaks plugged.
This commit is contained in:
Element Green 2006-11-23 18:49:36 +00:00
parent 4c68e10ab3
commit 20542770b4
9 changed files with 133 additions and 40 deletions

View File

@ -1,3 +1,27 @@
2006-11-22 Josh Green <jgreen@users.sourceforge.net>
* src/fluid_alsa.c (new_fluid_alsa_audio_driver2): Removed some ALSA
lib calls to set software parameters, which was likely causing the
100% CPU usage problem (not actually fixed in last update, not sure
which one is the culprit).
(fluid_alsa_seq_run): More changes in ALSA sequencer code, hopefully
it is right this time!
(delete_fluid_alsa_seq_driver): Memory leak fixed - wasn't freeing
array of sequencer file descriptors.
* src/fluid_chan.c: Memory leak fixes: Now deleting preset from channel
when channel is destroyed.
* src/fluid_cmd.c: Memory leak fix: strtok being deleted from command
shell when shell is destroyed.
* src/fluid_defsfont.c: Memory leak fixes: Freeing modulator lists in
preset and instrument zones, freeing zone names, freeing instruments
linked from preset zones, replaced use of "safe_malloc" with FLUID_MALLOC
macro, deleting instrument list in SFData, deleting samples in SFData,
freeing SFData structure.
* src/fluid_settings.c: Memory leak fix: freeing options in option
type settings.
* src/fluid_synth.c: Memory leak fixes: Freeing FX buffers and
right/left_buf.
2006-11-21 Josh Green <jgreen@users.sourceforge.net>
* src/fluid_alsa.c (new_fluid_alsa_audio_driver2): Modified all ALSA

View File

@ -296,19 +296,20 @@ new_fluid_alsa_audio_driver2(fluid_settings_t* settings,
FLUID_LOG(FLUID_ERR, "Failed to set start threshold.");
}
if (snd_pcm_sw_params_set_stop_threshold(dev->pcm, swparams, ~0u) != 0) {
FLUID_LOG(FLUID_ERR, "Cannot turn off stop threshold.");
}
// if (snd_pcm_sw_params_set_stop_threshold(dev->pcm, swparams, ~0u) != 0) {
// FLUID_LOG(FLUID_ERR, "Cannot turn off stop threshold.");
// }
if (snd_pcm_sw_params_set_silence_threshold(dev->pcm, swparams, 0) != 0) {
FLUID_LOG(FLUID_ERR, "Cannot set 0 silence threshold.");
}
// if (snd_pcm_sw_params_set_silence_threshold(dev->pcm, swparams, 0) != 0) {
// FLUID_LOG(FLUID_ERR, "Cannot set 0 silence threshold.");
// }
if (snd_pcm_sw_params_set_silence_size(dev->pcm, swparams, 0) != 0) {
FLUID_LOG(FLUID_ERR, "Cannot set 0 silence size.");
}
// if (snd_pcm_sw_params_set_silence_size(dev->pcm, swparams, 0) != 0) {
// FLUID_LOG(FLUID_ERR, "Cannot set 0 silence size.");
// }
if (snd_pcm_sw_params_set_avail_min(dev->pcm, swparams, period_size / 2) != 0) {
// if (snd_pcm_sw_params_set_avail_min(dev->pcm, swparams, period_size / 2) != 0) {
if (snd_pcm_sw_params_set_avail_min(dev->pcm, swparams, period_size) != 0) {
FLUID_LOG(FLUID_ERR, "Software setup for minimum available frames failed.");
}
@ -1047,6 +1048,9 @@ delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p)
if (dev->seq_handle) {
snd_seq_close(dev->seq_handle);
}
if (dev->pfd) FLUID_FREE (dev->pfd);
FLUID_FREE(dev);
return FLUID_OK;
}
@ -1057,7 +1061,7 @@ delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p)
void*
fluid_alsa_seq_run(void* d)
{
int n, i;
int n, ev;
snd_seq_event_t *seq_ev;
fluid_midi_event_t evt;
fluid_alsa_seq_driver_t* dev = (fluid_alsa_seq_driver_t*) d;
@ -1082,20 +1086,24 @@ fluid_alsa_seq_run(void* d)
if (n < 0) {
perror("poll");
} else if (n > 0) { /* check for pending events */
while (snd_seq_event_input_pending (dev->seq_handle, 0))
// while (snd_seq_event_input_pending (dev->seq_handle, 0))
do
{
n = snd_seq_event_input(dev->seq_handle, &seq_ev); /* read the events */
ev = snd_seq_event_input(dev->seq_handle, &seq_ev); /* read the events */
/* Negative value indicates an error, ignore interrupted system call
* (-EPERM) and input event buffer overrun (-ENOSPC) */
if (n < 0 && n != -EPERM && n != -ENOSPC) /* FIXME - report buffer overrun? */
{
FLUID_LOG(FLUID_ERR, "Error while reading ALSA sequencer (code=%d)", n);
dev->status = FLUID_MIDI_DONE;
break;
}
/* Negative value indicates an error, ignore interrupted system call
* (-EPERM) and input event buffer overrun (-ENOSPC) */
if (ev < 0)
{ /* FIXME - report buffer overrun? */
if (ev != -EPERM && ev != -ENOSPC)
{
FLUID_LOG(FLUID_ERR, "Error while reading ALSA sequencer (code=%d)", ev);
dev->status = FLUID_MIDI_DONE;
}
break;
}
switch (seq_ev->type)
switch (seq_ev->type)
{
case SND_SEQ_EVENT_NOTEON:
evt.type = NOTE_ON;
@ -1142,9 +1150,10 @@ fluid_alsa_seq_run(void* d)
continue; /* unhandled event, next loop iteration */
}
/* send the events to the next link in the chain */
(*dev->driver.handler)(dev->driver.data, &evt);
/* send the events to the next link in the chain */
(*dev->driver.handler)(dev->driver.data, &evt);
}
while (ev > 0);
} /* if poll() > 0 */
} /* while (dev->status == FLUID_MIDI_LISTENING) */
pthread_exit(NULL);

View File

@ -41,6 +41,7 @@ new_fluid_channel(fluid_synth_t* synth, int num)
chan->synth = synth;
chan->channum = num;
chan->preset = NULL;
fluid_channel_init(chan);
fluid_channel_init_ctrl(chan);
@ -54,7 +55,10 @@ fluid_channel_init(fluid_channel_t* chan)
chan->prognum = (chan->channum == 9)? 0 : chan->channum;
chan->banknum = (chan->channum == 9)? 128 : 0;
chan->sfontnum = 0;
if (chan->preset) delete_fluid_preset (chan->preset);
chan->preset = fluid_synth_find_preset(chan->synth, chan->banknum, chan->prognum);
chan->interp_method = FLUID_INTERP_DEFAULT;
chan->tuning = NULL;
chan->nrpn_select = 0;
@ -106,6 +110,7 @@ fluid_channel_reset(fluid_channel_t* chan)
int
delete_fluid_channel(fluid_channel_t* chan)
{
if (chan->preset) delete_fluid_preset (chan->preset);
FLUID_FREE(chan);
return FLUID_OK;
}
@ -119,6 +124,7 @@ fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset)
fluid_preset_notify(chan->preset, FLUID_PRESET_UNSELECTED, chan->channum);
fluid_preset_notify(preset, FLUID_PRESET_SELECTED, chan->channum);
if (chan->preset) delete_fluid_preset (chan->preset);
chan->preset = preset;
return FLUID_OK;
}

View File

@ -257,6 +257,9 @@ void delete_fluid_shell(fluid_shell_t* shell)
if (shell->thread != NULL) {
delete_fluid_thread(shell->thread);
}
if (shell->st) delete_fluid_strtok (shell->st);
FLUID_FREE(shell);
}

View File

@ -949,6 +949,18 @@ new_fluid_preset_zone(char *name)
int
delete_fluid_preset_zone(fluid_preset_zone_t* zone)
{
fluid_mod_t *mod, *tmp;
mod = zone->mod;
while (mod) /* delete the modulators */
{
tmp = mod;
mod = mod->next;
fluid_mod_delete (tmp);
}
if (zone->name) FLUID_FREE (zone->name);
if (zone->inst) delete_fluid_inst (zone->inst);
FLUID_FREE(zone);
return FLUID_OK;
}
@ -1331,6 +1343,17 @@ new_fluid_inst_zone(char* name)
int
delete_fluid_inst_zone(fluid_inst_zone_t* zone)
{
fluid_mod_t *mod, *tmp;
mod = zone->mod;
while (mod) /* delete the modulators */
{
tmp = mod;
mod = mod->next;
fluid_mod_delete (tmp);
}
if (zone->name) FLUID_FREE (zone->name);
FLUID_FREE(zone);
return FLUID_OK;
}
@ -1770,8 +1793,12 @@ sfload_file (const char * fname)
return (NULL);
}
if (!(sf = safe_malloc (sizeof (SFData))))
err = TRUE;
if (!(sf = FLUID_NEW (SFData)))
{
FLUID_LOG(FLUID_ERR, "Out of memory");
err = TRUE;
}
if (!err)
{
memset (sf, 0, sizeof (SFData)); /* zero sfdata */
@ -1942,8 +1969,11 @@ process_info (int size, SFData * sf, FILE * fd)
" of %d bytes"), &chunk.id, chunk.size));
/* alloc for chunk id and da chunk */
if (!(item = safe_malloc (chunk.size + 1)))
return (FAIL);
if (!(item = FLUID_MALLOC (chunk.size + 1)))
{
FLUID_LOG(FLUID_ERR, "Out of memory");
return (FAIL);
}
/* attach to INFO list, sfont_close will cleanup if FAIL occurs */
sf->info = fluid_list_append (sf->info, item);
@ -3035,8 +3065,19 @@ sfont_free_data (SFData * sf)
FLUID_FREE (p->data);
p = fluid_list_next (p);
}
delete_fluid_list (sf->inst);
sf->inst = NULL;
p = sf->sample;
while (p)
{
FLUID_FREE (p->data);
p = fluid_list_next (p);
}
delete_fluid_list (sf->sample);
sf->sample = NULL;
FLUID_FREE (sf);
}
/* free all elements of a zone (Preset or Instrument) */
@ -3173,13 +3214,3 @@ safe_fseek (FILE * fd, long ofs, int whence)
}
return (OK);
}
void *
safe_malloc (size_t size)
{
void *ptr;
if (!(ptr = malloc (size)))
FLUID_LOG (FLUID_ERR, _("Attempted to allocate %d bytes"), (int) size);
return (ptr);
}

View File

@ -427,7 +427,6 @@ enum
#define ErrnoEnd ErrWrite
int gerr (int ev, char * fmt, ...);
void *safe_malloc (size_t size);
int safe_fread (void *buf, int count, FILE * fd);
int safe_fwrite (void *buf, int count, FILE * fd);
int safe_fseek (FILE * fd, long ofs, int whence);

View File

@ -92,7 +92,7 @@ new_fluid_dsound_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
/* check if the globals are initialized */
if (FLUID_HINSTANCE == NULL) {
FLUID_LOG(FLUID_ERR, "No hinstance needed for DirectSound");
FLUID_LOG(FLUID_ERR, "FluidSynth hinstance not set, which is needed for DirectSound");
return NULL;
}

View File

@ -66,6 +66,13 @@ static void delete_fluid_str_setting(fluid_str_setting_t* str)
FLUID_FREE(str->def);
}
if (str->options) {
fluid_list_t* list = str->options;
while (list) {
FLUID_FREE (list->data);
list = fluid_list_next(list);
}
delete_fluid_list(str->options);
}
FLUID_FREE(str);
@ -600,6 +607,7 @@ int fluid_settings_remove_option(fluid_settings_t* settings, char* name, char* s
while (list) {
char* option = (char*) fluid_list_get(list);
if (FLUID_STRCMP(s, option) == 0) {
FLUID_FREE (option);
setting->options = fluid_list_remove_link(setting->options, list);
return 1;
}

View File

@ -655,6 +655,7 @@ delete_fluid_synth(fluid_synth_t* synth)
}
FLUID_FREE(synth->left_ubuf);
}
FLUID_FREE(synth->left_buf);
if (synth->right_ubuf != NULL) {
for (i = 0; i < synth->nbuf; i++) {
@ -664,6 +665,7 @@ delete_fluid_synth(fluid_synth_t* synth)
}
FLUID_FREE(synth->right_ubuf);
}
FLUID_FREE(synth->right_buf);
if (synth->fx_left_ubuf != NULL) {
for (i = 0; i < 2; i++) {
@ -673,6 +675,17 @@ delete_fluid_synth(fluid_synth_t* synth)
}
FLUID_FREE(synth->fx_left_ubuf);
}
FLUID_FREE(synth->fx_left_buf);
if (synth->fx_right_ubuf != NULL) {
for (i = 0; i < 2; i++) {
if (synth->fx_right_ubuf[i] != NULL) {
FLUID_FREE(synth->fx_right_ubuf[i]);
}
}
FLUID_FREE(synth->fx_right_ubuf);
}
FLUID_FREE(synth->fx_right_buf);
/* release the reverb module */
if (synth->reverb != NULL) {