mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-03 17:42:21 +00:00
Add synth.lock-memory option (possibility to avoid mlock)
Closes ticket #111. Sometimes, e g in a fast-render scenario or other scenarios where low latency is not important, you can turn off mlock to reduce memory pressure (and thus allow the soundfont to swap to disk).
This commit is contained in:
parent
5f3568deee
commit
5b2e24a762
4 changed files with 54 additions and 39 deletions
|
@ -599,7 +599,8 @@ int main(int argc, char** argv)
|
|||
midi_in = 0;
|
||||
interactive = 0;
|
||||
with_server = 0;
|
||||
fluid_settings_setstr(settings, "player.timing-source", "sample");
|
||||
fluid_settings_setstr(settings, "player.timing-source", "sample");
|
||||
fluid_settings_setint(settings, "synth.lock-memory", 0);
|
||||
fluid_settings_setint(settings, "synth.parallel-render", 1); /* TODO: Fast_render should not need this, but currently do */
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* SFONT LOADER
|
||||
*/
|
||||
|
||||
fluid_sfloader_t* new_fluid_defsfloader()
|
||||
fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_sfloader_t* loader;
|
||||
|
||||
|
@ -41,7 +41,7 @@ fluid_sfloader_t* new_fluid_defsfloader()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
loader->data = NULL;
|
||||
loader->data = settings;
|
||||
loader->free = delete_fluid_defsfloader;
|
||||
loader->load = fluid_defsfloader_load;
|
||||
|
||||
|
@ -61,7 +61,7 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
|
|||
fluid_defsfont_t* defsfont;
|
||||
fluid_sfont_t* sfont;
|
||||
|
||||
defsfont = new_fluid_defsfont();
|
||||
defsfont = new_fluid_defsfont(loader->data);
|
||||
|
||||
if (defsfont == NULL) {
|
||||
return NULL;
|
||||
|
@ -200,12 +200,13 @@ int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth,
|
|||
* CACHED SAMPLEDATA LOADER
|
||||
*/
|
||||
|
||||
typedef struct _fluid_cached_sampledata_t{
|
||||
typedef struct _fluid_cached_sampledata_t {
|
||||
struct _fluid_cached_sampledata_t *next;
|
||||
|
||||
char* filename;
|
||||
time_t modification_time;
|
||||
int num_references;
|
||||
int mlock;
|
||||
|
||||
const short* sampledata;
|
||||
unsigned int samplesize;
|
||||
|
@ -231,7 +232,8 @@ static int fluid_get_file_modification_time(char *filename, time_t *modification
|
|||
#endif
|
||||
}
|
||||
|
||||
static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos, unsigned int samplesize, short **sampledata)
|
||||
static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
||||
unsigned int samplesize, short **sampledata, int try_mlock)
|
||||
{
|
||||
fluid_file fd = NULL;
|
||||
short *loaded_sampledata = NULL;
|
||||
|
@ -245,25 +247,27 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
modification_time = 0;
|
||||
}
|
||||
|
||||
cached_sampledata = all_cached_sampledata;
|
||||
while (cached_sampledata != NULL) {
|
||||
if (!strcmp(filename, cached_sampledata->filename)) {
|
||||
|
||||
if (cached_sampledata->modification_time == modification_time) {
|
||||
|
||||
if (cached_sampledata->samplesize != samplesize) {
|
||||
FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)",
|
||||
cached_sampledata->samplesize,samplesize);
|
||||
} else {
|
||||
|
||||
cached_sampledata->num_references++;
|
||||
loaded_sampledata = (short*) cached_sampledata->sampledata;
|
||||
goto success_exit;
|
||||
}
|
||||
}
|
||||
for (cached_sampledata = all_cached_sampledata; cached_sampledata; cached_sampledata = cached_sampledata->next) {
|
||||
if (strcmp(filename, cached_sampledata->filename))
|
||||
continue;
|
||||
if (cached_sampledata->modification_time != modification_time)
|
||||
continue;
|
||||
if (cached_sampledata->samplesize != samplesize) {
|
||||
FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)",
|
||||
cached_sampledata->samplesize, samplesize);
|
||||
continue;
|
||||
}
|
||||
|
||||
cached_sampledata = cached_sampledata->next;
|
||||
if (try_mlock && !cached_sampledata->mlock) {
|
||||
if (fluid_mlock(*sampledata, samplesize) != 0)
|
||||
FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
|
||||
else
|
||||
cached_sampledata->mlock = try_mlock;
|
||||
}
|
||||
|
||||
cached_sampledata->num_references++;
|
||||
loaded_sampledata = (short*) cached_sampledata->sampledata;
|
||||
goto success_exit;
|
||||
}
|
||||
|
||||
fd = FLUID_FOPEN(filename, "rb");
|
||||
|
@ -291,10 +295,21 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
FLUID_FCLOSE(fd);
|
||||
fd = NULL;
|
||||
|
||||
|
||||
cached_sampledata = (fluid_cached_sampledata_t*) FLUID_MALLOC(sizeof(fluid_cached_sampledata_t));
|
||||
if (cached_sampledata == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory.");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
/* Lock the memory to disable paging. It's okay if this fails. It
|
||||
probably means that the user doesn't have to required permission. */
|
||||
if (fluid_mlock(*sampledata, samplesize) != 0) {
|
||||
FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
|
||||
cached_sampledata->mlock = 0;
|
||||
if (try_mlock) {
|
||||
if (fluid_mlock(*sampledata, samplesize) != 0)
|
||||
FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
|
||||
else
|
||||
cached_sampledata->mlock = try_mlock;
|
||||
}
|
||||
|
||||
/* If this machine is big endian, the sample have to byte swapped */
|
||||
|
@ -312,12 +327,6 @@ static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
|
|||
}
|
||||
}
|
||||
|
||||
cached_sampledata = (fluid_cached_sampledata_t*) FLUID_MALLOC(sizeof(fluid_cached_sampledata_t));
|
||||
if (cached_sampledata == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory.");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
cached_sampledata->filename = (char*) FLUID_MALLOC(strlen(filename) + 1);
|
||||
if (cached_sampledata->filename == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory.");
|
||||
|
@ -373,7 +382,8 @@ static int fluid_cached_sampledata_unload(const short *sampledata)
|
|||
cached_sampledata->num_references--;
|
||||
|
||||
if (cached_sampledata->num_references == 0) {
|
||||
fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize);
|
||||
if (cached_sampledata->mlock)
|
||||
fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize);
|
||||
FLUID_FREE((short*) cached_sampledata->sampledata);
|
||||
FLUID_FREE(cached_sampledata->filename);
|
||||
|
||||
|
@ -416,7 +426,7 @@ static int fluid_cached_sampledata_unload(const short *sampledata)
|
|||
/*
|
||||
* new_fluid_defsfont
|
||||
*/
|
||||
fluid_defsfont_t* new_fluid_defsfont()
|
||||
fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_defsfont_t* sfont;
|
||||
|
||||
|
@ -432,6 +442,7 @@ fluid_defsfont_t* new_fluid_defsfont()
|
|||
sfont->sample = NULL;
|
||||
sfont->sampledata = NULL;
|
||||
sfont->preset = NULL;
|
||||
fluid_settings_getint(settings, "synth.lock-memory", &sfont->mlock);
|
||||
|
||||
return sfont;
|
||||
}
|
||||
|
@ -616,7 +627,8 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset
|
|||
int
|
||||
fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont)
|
||||
{
|
||||
return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos, sfont->samplesize, &sfont->sampledata);
|
||||
return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos,
|
||||
sfont->samplesize, &sfont->sampledata, sfont->mlock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -375,7 +375,7 @@ typedef struct _fluid_inst_zone_t fluid_inst_zone_t;
|
|||
|
||||
*/
|
||||
|
||||
fluid_sfloader_t* new_fluid_defsfloader(void);
|
||||
fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings);
|
||||
int delete_fluid_defsfloader(fluid_sfloader_t* loader);
|
||||
fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename);
|
||||
|
||||
|
@ -405,13 +405,14 @@ struct _fluid_defsfont_t
|
|||
short* sampledata; /* the sample data, loaded in ram */
|
||||
fluid_list_t* sample; /* the samples in this soundfont */
|
||||
fluid_defpreset_t* preset; /* the presets of this soundfont */
|
||||
int mlock; /* Should we try memlock (avoid swapping)? */
|
||||
|
||||
fluid_preset_t iter_preset; /* preset interface used in the iteration */
|
||||
fluid_defpreset_t* iter_cur; /* the current preset in the iteration */
|
||||
};
|
||||
|
||||
|
||||
fluid_defsfont_t* new_fluid_defsfont(void);
|
||||
fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings);
|
||||
int delete_fluid_defsfont(fluid_defsfont_t* sfont);
|
||||
int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file);
|
||||
char* fluid_defsfont_get_name(fluid_defsfont_t* sfont);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "fluid_settings.h"
|
||||
#include "fluid_sfont.h"
|
||||
#include "fluid_hash.h"
|
||||
#include "fluid_defsfont.h"
|
||||
|
||||
#ifdef TRAP_ON_FPE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -110,8 +111,6 @@ static void fluid_synth_set_gen_LOCAL (fluid_synth_t* synth, int chan,
|
|||
static void fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id);
|
||||
|
||||
|
||||
fluid_sfloader_t* new_fluid_defsfloader(void);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
|
@ -186,6 +185,8 @@ void fluid_synth_settings(fluid_settings_t* settings)
|
|||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.ladspa.active", 0, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_int(settings, "synth.lock-memory", 1, 0, 1,
|
||||
FLUID_HINT_TOGGLED, NULL, NULL);
|
||||
fluid_settings_register_str(settings, "midi.portname", "", 0, NULL, NULL);
|
||||
|
||||
fluid_settings_register_int(settings, "synth.polyphony",
|
||||
|
@ -676,7 +677,7 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
#endif
|
||||
|
||||
/* allocate and add the default sfont loader */
|
||||
loader = new_fluid_defsfloader();
|
||||
loader = new_fluid_defsfloader(settings);
|
||||
|
||||
if (loader == NULL) {
|
||||
FLUID_LOG(FLUID_WARN, "Failed to create the default SoundFont loader");
|
||||
|
|
Loading…
Reference in a new issue