mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 06:51:54 +00:00
Parallelize SF3 loading (#746)
This commit is contained in:
parent
4836ff15c4
commit
0d76403f9f
4 changed files with 57 additions and 25 deletions
|
@ -374,6 +374,7 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
|
|||
fluid_list_t *list;
|
||||
fluid_sample_t *sample;
|
||||
int sf3_file = (sfdata->version.major == 3);
|
||||
int sample_parsing_result = FLUID_OK;
|
||||
|
||||
/* For SF2 files, we load the sample data in one large block */
|
||||
if(!sf3_file)
|
||||
|
@ -392,6 +393,8 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
|
|||
}
|
||||
}
|
||||
|
||||
#pragma omp parallel
|
||||
#pragma omp single
|
||||
for(list = defsfont->sample; list; list = fluid_list_next(list))
|
||||
{
|
||||
sample = fluid_list_get(list);
|
||||
|
@ -400,13 +403,22 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
|
|||
{
|
||||
/* SF3 samples get loaded individually, as most (or all) of them are in Ogg Vorbis format
|
||||
* anyway */
|
||||
if(fluid_defsfont_load_sampledata(defsfont, sfdata, sample) == FLUID_FAILED)
|
||||
#pragma omp task firstprivate(sample,sfdata,defsfont) shared(sample_parsing_result) default(none)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to load sample '%s'", sample->name);
|
||||
return FLUID_FAILED;
|
||||
if(fluid_defsfont_load_sampledata(defsfont, sfdata, sample) == FLUID_FAILED)
|
||||
{
|
||||
#pragma omp critical
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to load sample '%s'", sample->name);
|
||||
sample_parsing_result = FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
|
||||
fluid_voice_optimize_sample(sample);
|
||||
}
|
||||
}
|
||||
|
||||
fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -414,12 +426,11 @@ int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdat
|
|||
sample->data = defsfont->sampledata;
|
||||
sample->data24 = defsfont->sample24data;
|
||||
fluid_sample_sanitize_loop(sample, defsfont->samplesize);
|
||||
fluid_voice_optimize_sample(sample);
|
||||
}
|
||||
|
||||
fluid_voice_optimize_sample(sample);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
return sample_parsing_result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -89,6 +89,7 @@ int fluid_samplecache_load(SFData *sf,
|
|||
|
||||
if(entry == NULL)
|
||||
{
|
||||
fluid_mutex_unlock(samplecache_mutex);
|
||||
entry = new_samplecache_entry(sf, sample_start, sample_end, sample_type, mtime);
|
||||
|
||||
if(entry == NULL)
|
||||
|
@ -97,8 +98,10 @@ int fluid_samplecache_load(SFData *sf,
|
|||
goto unlock_exit;
|
||||
}
|
||||
|
||||
fluid_mutex_lock(samplecache_mutex);
|
||||
samplecache_list = fluid_list_prepend(samplecache_list, entry);
|
||||
}
|
||||
fluid_mutex_unlock(samplecache_mutex);
|
||||
|
||||
if(try_mlock && !entry->mlocked)
|
||||
{
|
||||
|
@ -129,7 +132,6 @@ int fluid_samplecache_load(SFData *sf,
|
|||
ret = entry->sample_count;
|
||||
|
||||
unlock_exit:
|
||||
fluid_mutex_unlock(samplecache_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -422,6 +422,7 @@ SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs)
|
|||
|
||||
FLUID_MEMSET(sf, 0, sizeof(SFData));
|
||||
|
||||
fluid_rec_mutex_init(sf->mtx);
|
||||
sf->fcbs = fcbs;
|
||||
|
||||
if((sf->sffd = fcbs->fopen(fname)) == NULL)
|
||||
|
@ -530,6 +531,7 @@ void fluid_sffile_close(SFData *sf)
|
|||
SFPreset *preset;
|
||||
SFInst *inst;
|
||||
|
||||
fluid_rec_mutex_destroy(sf->mtx);
|
||||
if(sf->sffd)
|
||||
{
|
||||
sf->fcbs->fclose(sf->sffd);
|
||||
|
@ -2529,10 +2531,14 @@ static sf_count_t sfvio_seek(sf_count_t offset, int whence, void *user_data)
|
|||
goto fail; /* proper error handling not possible?? */
|
||||
}
|
||||
|
||||
if(sf->fcbs->fseek(sf->sffd, sf->samplepos + data->start + new_offset, SEEK_SET) != FLUID_FAILED)
|
||||
new_offset += data->start;
|
||||
fluid_rec_mutex_lock(sf->mtx);
|
||||
if (data->start <= new_offset && new_offset <= data->end &&
|
||||
sf->fcbs->fseek(sf->sffd, new_offset, SEEK_SET) != FLUID_FAILED)
|
||||
{
|
||||
data->offset = new_offset;
|
||||
data->offset = new_offset - data->start;
|
||||
}
|
||||
fluid_rec_mutex_unlock(sf->mtx);
|
||||
|
||||
fail:
|
||||
return data->offset;
|
||||
|
@ -2556,11 +2562,21 @@ static sf_count_t sfvio_read(void *ptr, sf_count_t count, void *user_data)
|
|||
return count;
|
||||
}
|
||||
|
||||
if(sf->fcbs->fread(ptr, count, sf->sffd) == FLUID_FAILED)
|
||||
fluid_rec_mutex_lock(sf->mtx);
|
||||
if (sf->fcbs->fseek(sf->sffd, data->start + data->offset, SEEK_SET) == FLUID_FAILED)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to read compressed sample data");
|
||||
return 0;
|
||||
FLUID_LOG(FLUID_ERR, "This should never happen: fseek failed in sfvoid_read()");
|
||||
count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sf->fcbs->fread(ptr, count, sf->sffd) == FLUID_FAILED)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to read compressed sample data");
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
fluid_rec_mutex_unlock(sf->mtx);
|
||||
|
||||
data->offset += count;
|
||||
|
||||
|
@ -2607,25 +2623,26 @@ static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigne
|
|||
|
||||
// Initialize file position indicator and SF_INFO structure
|
||||
sfdata.sffile = sf;
|
||||
sfdata.start = start_byte;
|
||||
sfdata.end = end_byte;
|
||||
sfdata.offset = 0;
|
||||
sfdata.start = sf->samplepos + start_byte;
|
||||
sfdata.end = sf->samplepos + end_byte;
|
||||
sfdata.offset = -1;
|
||||
|
||||
FLUID_MEMSET(&sfinfo, 0, sizeof(sfinfo));
|
||||
|
||||
/* Seek to beginning of Ogg Vorbis data in Soundfont */
|
||||
if(sf->fcbs->fseek(sf->sffd, sf->samplepos + start_byte, SEEK_SET) == FLUID_FAILED)
|
||||
/* Seek to sfdata.start, the beginning of Ogg Vorbis data in Soundfont */
|
||||
sfvio_seek(0, SEEK_SET, &sfdata);
|
||||
if (sfdata.offset != 0)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Failed to seek to compressd sample position");
|
||||
FLUID_LOG(FLUID_ERR, "Failed to seek to compressed sample position");
|
||||
return -1;
|
||||
}
|
||||
|
||||
FLUID_MEMSET(&sfinfo, 0, sizeof(sfinfo));
|
||||
|
||||
// Open sample as a virtual file
|
||||
sndfile = sf_open_virtual(&sfvio, SFM_READ, &sfinfo, &sfdata);
|
||||
|
||||
if(!sndfile)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "%s", sf_strerror(sndfile));
|
||||
FLUID_LOG(FLUID_ERR, "sf_open_virtual(): %s", sf_strerror(sndfile));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2662,7 +2679,7 @@ static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigne
|
|||
if(sf_readf_short(sndfile, wav_data, sfinfo.frames) < sfinfo.frames)
|
||||
{
|
||||
FLUID_LOG(FLUID_DBG, "Decompression failed!");
|
||||
FLUID_LOG(FLUID_ERR, "%s", sf_strerror(sndfile));
|
||||
FLUID_LOG(FLUID_ERR, "sf_readf_short(): %s", sf_strerror(sndfile));
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "fluid_list.h"
|
||||
#include "fluid_mod.h"
|
||||
#include "fluidsynth.h"
|
||||
#include "fluidsynth_priv.h"
|
||||
#include "fluid_sys.h"
|
||||
|
||||
|
||||
/* Sound Font structure defines */
|
||||
|
@ -159,6 +159,8 @@ struct _SFData
|
|||
FILE *sffd; /* loaded sfont file descriptor */
|
||||
const fluid_file_callbacks_t *fcbs; /* file callbacks used to read this file */
|
||||
|
||||
fluid_rec_mutex_t mtx; /* this mutex can be used to synchronize calls to fcbs when using multiple threads (e.g. SF3 loading) */
|
||||
|
||||
fluid_list_t *info; /* linked list of info strings (1st byte is ID) */
|
||||
fluid_list_t *preset; /* linked list of preset info */
|
||||
fluid_list_t *inst; /* linked list of instrument info */
|
||||
|
|
Loading…
Reference in a new issue