diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index f473db4c..e5749044 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -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; } /* diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index 2d70d7e8..64e9e9e7 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -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; } diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 6dbc307b..614dfe26 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -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; } diff --git a/src/sfloader/fluid_sffile.h b/src/sfloader/fluid_sffile.h index 9ee86b3d..8dc53c79 100644 --- a/src/sfloader/fluid_sffile.h +++ b/src/sfloader/fluid_sffile.h @@ -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 */