From 879a14163a0629b53056b79947f4e70e617c58d0 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 01/47] Move low-level soundfont loading functions to separate files --- src/CMakeLists.txt | 2 + src/sfloader/fluid_defsfont.c | 1635 -------------------------------- src/sfloader/fluid_defsfont.h | 293 +----- src/sfloader/fluid_sf2.c | 1652 +++++++++++++++++++++++++++++++++ src/sfloader/fluid_sf2.h | 312 +++++++ 5 files changed, 1967 insertions(+), 1927 deletions(-) create mode 100644 src/sfloader/fluid_sf2.c create mode 100644 src/sfloader/fluid_sf2.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 608564bf..15d1e7b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -129,6 +129,8 @@ set ( libfluidsynth_SOURCES sfloader/fluid_ramsfont.h sfloader/fluid_sfont.h sfloader/fluid_sfont.c + sfloader/fluid_sf2.c + sfloader/fluid_sf2.h rvoice/fluid_adsr_env.c rvoice/fluid_adsr_env.h rvoice/fluid_chorus.c diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index e8cf53ed..73c7a5b3 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -2033,1638 +2033,3 @@ static int uncompress_vorbis_sample(fluid_sample_t *sample) return FLUID_FAILED; } #endif - - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - - -/*=================================sfload.c======================== - Borrowed from Smurf SoundFont Editor by Josh Green - =================================================================*/ - -/* - functions for loading data from sfont files, with appropriate byte swapping - on big endian machines. Sfont IDs are not swapped because the ID read is - equivalent to the matching ID list in memory regardless of LE/BE machine -*/ - -#define READCHUNK(var,fd, fcbs) do { \ - if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ - return(FAIL); \ - ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \ -} while(0) - -#define READD(var,fd, fcbs) do { \ - uint32_t _temp; \ - if (fcbs->fread(&_temp, 4, fd) == FLUID_FAILED) \ - return(FAIL); \ - var = FLUID_LE32TOH(_temp); \ -} while(0) - -#define READW(var,fd, fcbs) do { \ - uint16_t _temp; \ - if (fcbs->fread(&_temp, 2, fd) == FLUID_FAILED) \ - return(FAIL); \ - var = FLUID_LE16TOH(_temp); \ -} while(0) - -#define READID(var,fd, fcbs) do { \ - if (fcbs->fread(var, 4, fd) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) - -#define READSTR(var,fd, fcbs) do { \ - if (fcbs->fread(var, 20, fd) == FLUID_FAILED) \ - return(FAIL); \ - (*var)[20] = '\0'; \ -} while(0) - -#define READB(var,fd, fcbs) do { \ - if (fcbs->fread(&var, 1, fd) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) - -#define FSKIP(size,fd, fcbs) do { \ - if (fcbs->fseek(fd, size, SEEK_CUR) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) - -#define FSKIPW(fd, fcbs) do { \ - if (fcbs->fseek(fd, 2, SEEK_CUR) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) - -/* removes and advances a fluid_list_t pointer */ -#define SLADVREM(list, item) do { \ - fluid_list_t *_temp = item; \ - item = fluid_list_next(item); \ - list = fluid_list_remove_link(list, _temp); \ - delete1_fluid_list(_temp); \ -} while(0) - -static int chunkid (unsigned int id); -static int load_body (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int read_listchunk (SFChunk * chunk, void * fd, const fluid_file_callbacks_t* fcbs); -static int process_info (int size, SFData * sf, void* fd, const fluid_file_callbacks_t* fcbs); -static int process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, - int * size, void * fd, const fluid_file_callbacks_t* fcbs); -static int process_pdta (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_phdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_pbag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_pgen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_ihdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_ibag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_imod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_igen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_shdr (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int fixup_pgen (SFData * sf); -static int fixup_igen (SFData * sf); -static int fixup_sample (SFData * sf); - -static const char idlist[] = { - "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" - "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24" -}; - -/* sound font file load functions */ -static int -chunkid (unsigned int id) -{ - unsigned int i; - unsigned int *p; - - p = (unsigned int *) & idlist; - for (i = 0; i < sizeof (idlist) / sizeof (int); i++, p += 1) - if (*p == id) - return (i + 1); - - return (UNKN_ID); -} - -SFData * -sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs) -{ - SFData *sf = NULL; - void *fd; - int fsize = 0; - int err = FALSE; - - if ((fd = fcbs->fopen (fname)) == NULL) - { - FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname); - return (NULL); - } - - if (!(sf = FLUID_NEW (SFData))) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - fclose(fd); - err = TRUE; - } - - if (!err) - { - memset (sf, 0, sizeof (SFData)); /* zero sfdata */ - sf->fname = FLUID_STRDUP (fname); /* copy file name */ - sf->sffd = fd; - } - - /* get size of file */ - if (!err && fcbs->fseek (fd, 0L, SEEK_END) == FLUID_FAILED) - { /* seek to end of file */ - err = TRUE; - FLUID_LOG (FLUID_ERR, _("Seek to end of file failed")); - } - if (!err && (fsize = fcbs->ftell (fd)) == FLUID_FAILED) - { /* position = size */ - err = TRUE; - FLUID_LOG (FLUID_ERR, _("Get end of file position failed")); - } - if (!err) - rewind (fd); - - if (!err && !load_body (fsize, sf, fd, fcbs)) - err = TRUE; /* load the sfont */ - - if (err) - { - if (sf) - sfont_close (sf, fcbs); - return (NULL); - } - - return (sf); -} - -static int -load_body (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - SFChunk chunk; - - READCHUNK (&chunk, fd, fcbs); /* load RIFF chunk */ - if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */ - FLUID_LOG (FLUID_ERR, _("Not a RIFF file")); - return (FAIL); - } - - READID (&chunk.id, fd, fcbs); /* load file ID */ - if (chunkid (chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ - FLUID_LOG (FLUID_ERR, _("Not a SoundFont file")); - return (FAIL); - } - - if (chunk.size != size - 8) { - gerr (ErrCorr, _("SoundFont file size mismatch")); - return (FAIL); - } - - /* Process INFO block */ - if (!read_listchunk (&chunk, fd, fcbs)) - return (FAIL); - if (chunkid (chunk.id) != INFO_ID) - return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk"))); - if (!process_info (chunk.size, sf, fd, fcbs)) - return (FAIL); - - /* Process sample chunk */ - if (!read_listchunk (&chunk, fd, fcbs)) - return (FAIL); - if (chunkid (chunk.id) != SDTA_ID) - return (gerr (ErrCorr, - _("Invalid ID found when expecting SAMPLE chunk"))); - if (!process_sdta (chunk.size, sf, fd, fcbs)) - return (FAIL); - - /* process HYDRA chunk */ - if (!read_listchunk (&chunk, fd, fcbs)) - return (FAIL); - if (chunkid (chunk.id) != PDTA_ID) - return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk"))); - if (!process_pdta (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!fixup_pgen (sf)) - return (FAIL); - if (!fixup_igen (sf)) - return (FAIL); - if (!fixup_sample (sf)) - return (FAIL); - - /* sort preset list by bank, preset # */ - sf->preset = fluid_list_sort (sf->preset, - (fluid_compare_func_t) sfont_preset_compare_func); - - return (OK); -} - -static int -read_listchunk (SFChunk * chunk, void * fd, const fluid_file_callbacks_t* fcbs) -{ - READCHUNK (chunk, fd, fcbs); /* read list chunk */ - if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */ - return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse"))); - READID (&chunk->id, fd, fcbs); /* read id string */ - chunk->size -= 4; - return (OK); -} - -static int -process_info (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - SFChunk chunk; - unsigned char id; - char *item; - unsigned short ver; - - while (size > 0) - { - READCHUNK (&chunk, fd, fcbs); - size -= 8; - - id = chunkid (chunk.id); - - if (id == IFIL_ID) - { /* sound font version chunk? */ - if (chunk.size != 4) - return (gerr (ErrCorr, - _("Sound font version info chunk has invalid size"))); - - READW (ver, fd, fcbs); - sf->version.major = ver; - READW (ver, fd, fcbs); - sf->version.minor = ver; - - if (sf->version.major < 2) { - FLUID_LOG (FLUID_ERR, - _("Sound font version is %d.%d which is not" - " supported, convert to version 2.0x"), - sf->version.major, - sf->version.minor); - return (FAIL); - } - - if (sf->version.major == 3) { -#if !LIBSNDFILE_SUPPORT - FLUID_LOG (FLUID_WARN, - _("Sound font version is %d.%d but fluidsynth was compiled without" - " support for (v3.x)"), - sf->version.major, - sf->version.minor); - return (FAIL); -#endif - } - else if (sf->version.major > 2) { - FLUID_LOG (FLUID_WARN, - _("Sound font version is %d.%d which is newer than" - " what this version of fluidsynth was designed for (v2.0x)"), - sf->version.major, - sf->version.minor); - return (FAIL); - } - } - else if (id == IVER_ID) - { /* ROM version chunk? */ - if (chunk.size != 4) - return (gerr (ErrCorr, - _("ROM version info chunk has invalid size"))); - - READW (ver, fd, fcbs); - sf->romver.major = ver; - READW (ver, fd, fcbs); - sf->romver.minor = ver; - } - else if (id != UNKN_ID) - { - if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) - || (chunk.size % 2)) - return (gerr (ErrCorr, - _("INFO sub chunk %.4s has invalid chunk size" - " of %d bytes"), &chunk.id, chunk.size)); - - /* alloc for chunk id and da chunk */ - 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); - - *(unsigned char *) item = id; - if (fcbs->fread(&item[1], chunk.size, fd) == FLUID_FAILED) - return (FAIL); - - /* force terminate info item (don't forget uint8 info ID) */ - *(item + chunk.size) = '\0'; - } - else - return (gerr (ErrCorr, _("Invalid chunk id in INFO chunk"))); - size -= chunk.size; - } - - if (size < 0) - return (gerr (ErrCorr, _("INFO chunk size mismatch"))); - - return (OK); -} - -static int -process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - SFChunk chunk; - - if (size == 0) - return (OK); /* no sample data? */ - - /* read sub chunk */ - READCHUNK (&chunk, fd, fcbs); - size -= 8; - - if (chunkid (chunk.id) != SMPL_ID) - return (gerr (ErrCorr, - _("Expected SMPL chunk found invalid id instead"))); - - /* SDTA chunk may also contain sm24 chunk for 24 bit samples - * (not yet supported), only an error if SMPL chunk size is - * greater than SDTA. */ - if (chunk.size > size) - return (gerr (ErrCorr, _("SDTA chunk size mismatch"))); - - /* sample data follows */ - sf->samplepos = fcbs->ftell (fd); - - /* used in fixup_sample() to check validity of sample headers */ - sf->samplesize = chunk.size; - - FSKIP (chunk.size, fd, fcbs); - size -= chunk.size; - - if(sf->version.major >= 2 && sf->version.minor >= 4) - { - /* any chance to find another chunk here? */ - if(size > 8) - { - /* read sub chunk */ - READCHUNK (&chunk, fd, fcbs); - size -= 8; - - if (chunkid (chunk.id) == SM24_ID) - { - int sm24size, sdtahalfsize; - - FLUID_LOG(FLUID_DBG, "Found SM24 chunk"); - if (chunk.size > size) - { - FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24"); - goto ret; // no error - } - - sdtahalfsize = sf->samplesize/2; - /* + 1 byte in the case that half the size of smpl chunk is an odd value */ - sdtahalfsize += sdtahalfsize%2; - sm24size = chunk.size; - - if (sdtahalfsize != sm24size) - { - FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != 0x%X), ignoring SM24", sm24size, sdtahalfsize); - goto ret; // no error - } - - /* sample data24 follows */ - sf->sample24pos = fcbs->ftell (fd); - sf->sample24size = sm24size; - } - } - } - -ret: - FSKIP (size, fd, fcbs); - - return (OK); -} - -static int -pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, - int * size, void * fd, const fluid_file_callbacks_t* fcbs) -{ - unsigned int id; - const char *expstr; - - expstr = CHNKIDSTR (expid); /* in case we need it */ - - READCHUNK (chunk, fd, fcbs); - *size -= 8; - - if ((id = chunkid (chunk->id)) != expid) - return (gerr (ErrCorr, _("Expected" - " PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr)); - - if (chunk->size % reclen) /* valid chunk size? */ - return (gerr (ErrCorr, - _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, - reclen)); - if ((*size -= chunk->size) < 0) - return (gerr (ErrCorr, - _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr)); - return (OK); -} - -static int -process_pdta (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - SFChunk chunk; - - if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_phdr (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_pbag (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_pmod (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_pgen (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_ihdr (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_ibag (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_imod (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_igen (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_shdr (chunk.size, sf, fd, fcbs)) - return (FAIL); - - return (OK); -} - -/* preset header loader */ -static int -load_phdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - int i, i2; - SFPreset *p, *pr = NULL; /* ptr to current & previous preset */ - unsigned short zndx, pzndx = 0; - - if (size % SFPHDRSIZE || size == 0) - return (gerr (ErrCorr, _("Preset header chunk size is invalid"))); - - i = size / SFPHDRSIZE - 1; - if (i == 0) - { /* at least one preset + term record */ - FLUID_LOG (FLUID_WARN, _("File contains no presets")); - FSKIP (SFPHDRSIZE, fd, fcbs); - return (OK); - } - - for (; i > 0; i--) - { /* load all preset headers */ - p = FLUID_NEW (SFPreset); - sf->preset = fluid_list_append (sf->preset, p); - p->zone = NULL; /* In case of failure, sfont_close can cleanup */ - READSTR (&p->name, fd, fcbs); /* possible read failure ^ */ - READW (p->prenum, fd, fcbs); - READW (p->bank, fd, fcbs); - READW (zndx, fd, fcbs); - READD (p->libr, fd, fcbs); - READD (p->genre, fd, fcbs); - READD (p->morph, fd, fcbs); - - if (pr) - { /* not first preset? */ - if (zndx < pzndx) - return (gerr (ErrCorr, _("Preset header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - { - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - } - else if (zndx > 0) /* 1st preset, warn if ofs >0 */ - FLUID_LOG (FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx); - pr = p; /* update preset ptr */ - pzndx = zndx; - } - - FSKIP (24, fd, fcbs); - READW (zndx, fd, fcbs); /* Read terminal generator index */ - FSKIP (12, fd, fcbs); - - if (zndx < pzndx) - return (gerr (ErrCorr, _("Preset header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - { - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - - return (OK); -} - -/* preset bag loader */ -static int -load_pbag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2; - SFZone *z, *pz = NULL; - unsigned short genndx, modndx; - unsigned short pgenndx = 0, pmodndx = 0; - unsigned short i; - - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr (ErrCorr, _("Preset bag chunk size is invalid"))); - - p = sf->preset; - while (p) - { /* traverse through presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse preset's zones */ - if ((size -= SFBAGSIZE) < 0) - return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); - z = FLUID_NEW (SFZone); - p2->data = z; - z->gen = NULL; /* Init gen and mod before possible failure, */ - z->mod = NULL; /* to ensure proper cleanup (sfont_close) */ - READW (genndx, fd, fcbs); /* possible read failure ^ */ - READW (modndx, fd, fcbs); - z->instsamp = NULL; - - if (pz) - { /* if not first zone */ - if (genndx < pgenndx) - return (gerr (ErrCorr, - _("Preset bag generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, - _("Preset bag modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - } - pz = z; /* update previous zone ptr */ - pgenndx = genndx; /* update previous zone gen index */ - pmodndx = modndx; /* update previous zone mod index */ - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - size -= SFBAGSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); - - READW (genndx, fd, fcbs); - READW (modndx, fd, fcbs); - - if (!pz) - { - if (genndx > 0) - FLUID_LOG (FLUID_WARN, _("No preset generators and terminal index not 0")); - if (modndx > 0) - FLUID_LOG (FLUID_WARN, _("No preset modulators and terminal index not 0")); - return (OK); - } - - if (genndx < pgenndx) - return (gerr (ErrCorr, _("Preset bag generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, _("Preset bag modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - - return (OK); -} - -/* preset modulator loader */ -static int -load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2, *p3; - SFMod *m; - - p = sf->preset; - while (p) - { /* traverse through all presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse this preset's zones */ - p3 = ((SFZone *) (p2->data))->mod; - while (p3) - { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) - return (gerr (ErrCorr, - _("Preset modulator chunk size mismatch"))); - m = FLUID_NEW (SFMod); - p3->data = m; - READW (m->src, fd, fcbs); - READW (m->dest, fd, fcbs); - READW (m->amount, fd, fcbs); - READW (m->amtsrc, fd, fcbs); - READW (m->trans, fd, fcbs); - p3 = fluid_list_next (p3); - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - /* - If there isn't even a terminal record - Hmmm, the specs say there should be one, but.. - */ - if (size == 0) - return (OK); - - size -= SFMODSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset modulator chunk size mismatch"))); - FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */ - - return (OK); -} - -/* ------------------------------------------------------------------- - * preset generator loader - * generator (per preset) loading rules: - * Zones with no generators or modulators shall be annihilated - * Global zone must be 1st zone, discard additional ones (instrumentless zones) - * - * generator (per zone) loading rules (in order of decreasing precedence): - * KeyRange is 1st in list (if exists), else discard - * if a VelRange exists only preceded by a KeyRange, else discard - * if a generator follows an instrument discard it - * if a duplicate generator exists replace previous one - * ------------------------------------------------------------------- */ -static int -load_pgen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; - SFZone *z; - SFGen *g; - SFGenAmount genval; - unsigned short genid; - int level, skip, drop, gzone, discarded; - - p = sf->preset; - while (p) - { /* traverse through all presets */ - gzone = FALSE; - discarded = FALSE; - p2 = ((SFPreset *) (p->data))->zone; - if (p2) - hz = &p2; - while (p2) - { /* traverse preset's zones */ - level = 0; - z = (SFZone *) (p2->data); - p3 = z->gen; - while (p3) - { /* load zone's generators */ - dup = NULL; - skip = FALSE; - drop = FALSE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Preset generator chunk size mismatch"))); - - READW (genid, fd, fcbs); - - if (genid == Gen_KeyRange) - { /* nothing precedes */ - if (level == 0) - { - level = 1; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_VelRange) - { /* only KeyRange precedes */ - if (level <= 1) - { - level = 2; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_Instrument) - { /* inst is last gen */ - level = 3; - READW (genval.uword, fd, fcbs); - ((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1); - break; /* break out of generator loop */ - } - else - { - level = 2; - if (gen_validp (genid)) - { /* generator valid? */ - READW (genval.sword, fd, fcbs); - dup = gen_inlist (genid, z->gen); - } - else - skip = TRUE; - } - - if (!skip) - { - if (!dup) - { /* if gen ! dup alloc new */ - g = FLUID_NEW (SFGen); - p3->data = g; - g->id = genid; - } - else - { - g = (SFGen *) (dup->data); /* ptr to orig gen */ - drop = TRUE; - } - g->amount = genval; - } - else - { /* Skip this generator */ - discarded = TRUE; - drop = TRUE; - FSKIPW (fd, fcbs); - } - - if (!drop) - p3 = fluid_list_next (p3); /* next gen */ - else - SLADVREM (z->gen, p3); /* drop place holder */ - - } /* generator loop */ - - if (level == 3) - SLADVREM (z->gen, p3); /* zone has inst? */ - else - { /* congratulations its a global zone */ - if (!gzone) - { /* Prior global zones? */ - gzone = TRUE; - - /* if global zone is not 1st zone, relocate */ - if (*hz != p2) - { - void* save = p2->data; - FLUID_LOG (FLUID_WARN, - _("Preset \"%s\": Global zone is not first zone"), - ((SFPreset *) (p->data))->name); - SLADVREM (*hz, p2); - *hz = fluid_list_prepend (*hz, save); - continue; - } - } - else - { /* previous global zone exists, discard */ - FLUID_LOG (FLUID_WARN, - _("Preset \"%s\": Discarding invalid global zone"), - ((SFPreset *) (p->data))->name); - sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); - } - } - - while (p3) - { /* Kill any zones following an instrument */ - discarded = TRUE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Preset generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); - SLADVREM (z->gen, p3); - } - - p2 = fluid_list_next (p2); /* next zone */ - } - if (discarded) - FLUID_LOG(FLUID_WARN, - _("Preset \"%s\": Some invalid generators were discarded"), - ((SFPreset *) (p->data))->name); - p = fluid_list_next (p); - } - - /* in case there isn't a terminal record */ - if (size == 0) - return (OK); - - size -= SFGENSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */ - - return (OK); -} - -/* instrument header loader */ -static int -load_ihdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - int i, i2; - SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ - unsigned short zndx, pzndx = 0; - - if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ - return (gerr (ErrCorr, _("Instrument header has invalid size"))); - - size = size / SFIHDRSIZE - 1; - if (size == 0) - { /* at least one preset + term record */ - FLUID_LOG (FLUID_WARN, _("File contains no instruments")); - FSKIP (SFIHDRSIZE, fd, fcbs); - return (OK); - } - - for (i = 0; i < size; i++) - { /* load all instrument headers */ - p = FLUID_NEW (SFInst); - sf->inst = fluid_list_append (sf->inst, p); - p->zone = NULL; /* For proper cleanup if fail (sfont_close) */ - READSTR (&p->name, fd, fcbs); /* Possible read failure ^ */ - READW (zndx, fd, fcbs); - - if (pr) - { /* not first instrument? */ - if (zndx < pzndx) - return (gerr (ErrCorr, - _("Instrument header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - else if (zndx > 0) /* 1st inst, warn if ofs >0 */ - FLUID_LOG (FLUID_WARN, _("%d instrument zones not referenced, discarding"), - zndx); - pzndx = zndx; - pr = p; /* update instrument ptr */ - } - - FSKIP (20, fd, fcbs); - READW (zndx, fd, fcbs); - - if (zndx < pzndx) - return (gerr (ErrCorr, _("Instrument header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - pr->zone = fluid_list_prepend (pr->zone, NULL); - - return (OK); -} - -/* instrument bag loader */ -static int -load_ibag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2; - SFZone *z, *pz = NULL; - unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0; - int i; - - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr (ErrCorr, _("Instrument bag chunk size is invalid"))); - - p = sf->inst; - while (p) - { /* traverse through inst */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* load this inst's zones */ - if ((size -= SFBAGSIZE) < 0) - return (gerr (ErrCorr, _("Instrument bag chunk size mismatch"))); - z = FLUID_NEW (SFZone); - p2->data = z; - z->gen = NULL; /* In case of failure, */ - z->mod = NULL; /* sfont_close can clean up */ - READW (genndx, fd, fcbs); /* READW = possible read failure */ - READW (modndx, fd, fcbs); - z->instsamp = NULL; - - if (pz) - { /* if not first zone */ - if (genndx < pgenndx) - return (gerr (ErrCorr, - _("Instrument generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, - _("Instrument modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - } - pz = z; /* update previous zone ptr */ - pgenndx = genndx; - pmodndx = modndx; - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - size -= SFBAGSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Instrument chunk size mismatch"))); - - READW (genndx, fd, fcbs); - READW (modndx, fd, fcbs); - - if (!pz) - { /* in case that all are no zoners */ - if (genndx > 0) - FLUID_LOG (FLUID_WARN, - _("No instrument generators and terminal index not 0")); - if (modndx > 0) - FLUID_LOG (FLUID_WARN, - _("No instrument modulators and terminal index not 0")); - return (OK); - } - - if (genndx < pgenndx) - return (gerr (ErrCorr, _("Instrument generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, _("Instrument modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - - return (OK); -} - -/* instrument modulator loader */ -static int -load_imod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2, *p3; - SFMod *m; - - p = sf->inst; - while (p) - { /* traverse through all inst */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* traverse this inst's zones */ - p3 = ((SFZone *) (p2->data))->mod; - while (p3) - { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) - return (gerr (ErrCorr, - _("Instrument modulator chunk size mismatch"))); - m = FLUID_NEW (SFMod); - p3->data = m; - READW (m->src, fd, fcbs); - READW (m->dest, fd, fcbs); - READW (m->amount, fd, fcbs); - READW (m->amtsrc, fd, fcbs); - READW (m->trans, fd, fcbs); - p3 = fluid_list_next (p3); - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - /* - If there isn't even a terminal record - Hmmm, the specs say there should be one, but.. - */ - if (size == 0) - return (OK); - - size -= SFMODSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch"))); - FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */ - - return (OK); -} - -/* load instrument generators (see load_pgen for loading rules) */ -static int -load_igen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; - SFZone *z; - SFGen *g; - SFGenAmount genval; - unsigned short genid; - int level, skip, drop, gzone, discarded; - - p = sf->inst; - while (p) - { /* traverse through all instruments */ - gzone = FALSE; - discarded = FALSE; - p2 = ((SFInst *) (p->data))->zone; - if (p2) - hz = &p2; - while (p2) - { /* traverse this instrument's zones */ - level = 0; - z = (SFZone *) (p2->data); - p3 = z->gen; - while (p3) - { /* load zone's generators */ - dup = NULL; - skip = FALSE; - drop = FALSE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); - - READW (genid, fd, fcbs); - - if (genid == Gen_KeyRange) - { /* nothing precedes */ - if (level == 0) - { - level = 1; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_VelRange) - { /* only KeyRange precedes */ - if (level <= 1) - { - level = 2; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_SampleId) - { /* sample is last gen */ - level = 3; - READW (genval.uword, fd, fcbs); - ((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1); - break; /* break out of generator loop */ - } - else - { - level = 2; - if (gen_valid (genid)) - { /* gen valid? */ - READW (genval.sword, fd, fcbs); - dup = gen_inlist (genid, z->gen); - } - else - skip = TRUE; - } - - if (!skip) - { - if (!dup) - { /* if gen ! dup alloc new */ - g = FLUID_NEW (SFGen); - p3->data = g; - g->id = genid; - } - else - { - g = (SFGen *) (dup->data); - drop = TRUE; - } - g->amount = genval; - } - else - { /* skip this generator */ - discarded = TRUE; - drop = TRUE; - FSKIPW (fd, fcbs); - } - - if (!drop) - p3 = fluid_list_next (p3); /* next gen */ - else - SLADVREM (z->gen, p3); - - } /* generator loop */ - - if (level == 3) - SLADVREM (z->gen, p3); /* zone has sample? */ - else - { /* its a global zone */ - if (!gzone) - { - gzone = TRUE; - - /* if global zone is not 1st zone, relocate */ - if (*hz != p2) - { - void* save = p2->data; - FLUID_LOG (FLUID_WARN, - _("Instrument \"%s\": Global zone is not first zone"), - ((SFPreset *) (p->data))->name); - SLADVREM (*hz, p2); - *hz = fluid_list_prepend (*hz, save); - continue; - } - } - else - { /* previous global zone exists, discard */ - FLUID_LOG (FLUID_WARN, - _("Instrument \"%s\": Discarding invalid global zone"), - ((SFInst *) (p->data))->name); - sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); - } - } - - while (p3) - { /* Kill any zones following a sample */ - discarded = TRUE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Instrument generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); - SLADVREM (z->gen, p3); - } - - p2 = fluid_list_next (p2); /* next zone */ - } - if (discarded) - FLUID_LOG(FLUID_WARN, - _("Instrument \"%s\": Some invalid generators were discarded"), - ((SFInst *) (p->data))->name); - p = fluid_list_next (p); - } - - /* for those non-terminal record cases, grr! */ - if (size == 0) - return (OK); - - size -= SFGENSIZE; - if (size != 0) - return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */ - - return (OK); -} - -/* sample header loader */ -static int -load_shdr (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - unsigned int i; - SFSample *p; - - if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ - return (gerr (ErrCorr, _("Sample header has invalid size"))); - - size = size / SFSHDRSIZE - 1; - if (size == 0) - { /* at least one sample + term record? */ - FLUID_LOG (FLUID_WARN, _("File contains no samples")); - FSKIP (SFSHDRSIZE, fd, fcbs); - return (OK); - } - - /* load all sample headers */ - for (i = 0; i < size; i++) - { - p = FLUID_NEW (SFSample); - sf->sample = fluid_list_append (sf->sample, p); - READSTR (&p->name, fd, fcbs); - READD (p->start, fd, fcbs); - READD (p->end, fd, fcbs); /* - end, loopstart and loopend */ - READD (p->loopstart, fd, fcbs); /* - will be checked and turned into */ - READD (p->loopend, fd, fcbs); /* - offsets in fixup_sample() */ - READD (p->samplerate, fd, fcbs); - READB (p->origpitch, fd, fcbs); - READB (p->pitchadj, fd, fcbs); - FSKIPW (fd, fcbs); /* skip sample link */ - READW (p->sampletype, fd, fcbs); - p->samfile = 0; - } - - FSKIP (SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */ - - return (OK); -} - -/* "fixup" (inst # -> inst ptr) instrument references in preset list */ -static int -fixup_pgen (SFData * sf) -{ - fluid_list_t *p, *p2, *p3; - SFZone *z; - int i; - - p = sf->preset; - while (p) - { - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse this preset's zones */ - z = (SFZone *) (p2->data); - if ((i = FLUID_POINTER_TO_INT (z->instsamp))) - { /* load instrument # */ - p3 = fluid_list_nth (sf->inst, i - 1); - if (!p3) - return (gerr (ErrCorr, - _("Preset %03d %03d: Invalid instrument reference"), - ((SFPreset *) (p->data))->bank, - ((SFPreset *) (p->data))->prenum)); - z->instsamp = p3; - } - else - z->instsamp = NULL; - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - return (OK); -} - -/* "fixup" (sample # -> sample ptr) sample references in instrument list */ -static int -fixup_igen (SFData * sf) -{ - fluid_list_t *p, *p2, *p3; - SFZone *z; - int i; - - p = sf->inst; - while (p) - { - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* traverse instrument's zones */ - z = (SFZone *) (p2->data); - if ((i = FLUID_POINTER_TO_INT (z->instsamp))) - { /* load sample # */ - p3 = fluid_list_nth (sf->sample, i - 1); - if (!p3) - return (gerr (ErrCorr, - _("Instrument \"%s\": Invalid sample reference"), - ((SFInst *) (p->data))->name)); - z->instsamp = p3; - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); - } - - return (OK); -} - -/* convert sample end, loopstart and loopend to offsets and check if valid */ -static int -fixup_sample (SFData * sf) -{ - fluid_list_t *p; - SFSample *sam; - int invalid_loops=FALSE; - int invalid_loopstart; - int invalid_loopend, loopend_end_mismatch; - unsigned int total_bytes = sf->samplesize; - unsigned int total_samples = total_bytes / FLUID_MEMBER_SIZE(fluid_defsfont_t, sampledata[0]); - - p = sf->sample; - while (p) - { - unsigned int max_end; - - sam = (SFSample *) (p->data); - - /* Standard SoundFont files (SF2) use sample word indices for sample start and end pointers, - * but SF3 files with Ogg Vorbis compression use byte indices for start and end. */ - max_end = (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) ? total_bytes : total_samples; - - /* ROM samples are unusable for us by definition, so simply ignore them. */ - if (sam->sampletype & FLUID_SAMPLETYPE_ROM) - { - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - goto next_sample; - } - - /* If end is over the sample data chunk or sam start is greater than 4 - * less than the end (at least 4 samples). - * - * FIXME: where does this number 4 come from? And do we need a different number for SF3 files? - * Maybe we should check for the minimum Ogg Vorbis headers size? */ - if ((sam->end > max_end) || (sam->start > (sam->end - 4))) - { - FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid," - " disabling and will not be saved"), sam->name); - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - goto next_sample; - } - - /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop */ - invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); - /* while loopend is the first point AFTER the last sample of the loop. - * this is as it should be. however we cannot be sure whether any of sam.loopend or sam.end - * is correct. hours of thinking through this have concluded, that it would be best practice - * to mangle with loops as little as necessary by only making sure loopend is within - * max_end. incorrect soundfont shall preferably fail loudly. */ - invalid_loopend = (sam->loopend > max_end) || (sam->loopstart >= sam->loopend); - - loopend_end_mismatch = (sam->loopend > sam->end); - - if (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) - { - /* - * compressed samples get fixed up after decompression - * - * however we cant use the logic below, because uncompressed samples are stored in individual buffers - */ - } - else if (invalid_loopstart || invalid_loopend || loopend_end_mismatch) /* loop is fowled?? (cluck cluck :) */ - { - /* though illegal, loopend may be set to loopstart to disable loop */ - /* is it worth informing the user? */ - invalid_loops |= (sam->loopend != sam->loopstart); - - /* force incorrect loop points into the sample range, ignore padding */ - if(invalid_loopstart) - { - FLUID_LOG (FLUID_DBG, _("Sample '%s' has unusable loop start '%d'," - " setting to sample start at '%d'"), sam->name, sam->loopstart, sam->start); - sam->loopstart = sam->start; - } - - if(invalid_loopend) - { - FLUID_LOG (FLUID_DBG, _("Sample '%s' has unusable loop stop '%d'," - " setting to sample stop at '%d'"), sam->name, sam->loopend, sam->end); - /* since at this time sam->end points after valid sample data (will correct that few lines below), - * set loopend to that first invalid sample, since it should never be played, but instead the last - * valid sample will be played */ - sam->loopend = sam->end; - } - else if(loopend_end_mismatch) - { - FLUID_LOG (FLUID_DBG, _("Sample '%s' has invalid loop stop '%d'," - " sample stop at '%d', using it anyway"), sam->name, sam->loopend, sam->end); - } - } - - /* convert sample end, loopstart, loopend to offsets from sam->start */ - sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */ - sam->loopstart -= sam->start; - sam->loopend -= sam->start; - -next_sample: - p = fluid_list_next (p); - } - - if(invalid_loops) - { - FLUID_LOG (FLUID_WARN, _("Found samples with invalid loops, audible glitches possible.")); - } - - return (OK); -} - -/*=================================sfont.c======================== - Smurf SoundFont Editor - ================================================================*/ - - -/* optimum chunk area sizes (could be more optimum) */ -#define PRESET_CHUNK_OPTIMUM_AREA 256 -#define INST_CHUNK_OPTIMUM_AREA 256 -#define SAMPLE_CHUNK_OPTIMUM_AREA 256 -#define ZONE_CHUNK_OPTIMUM_AREA 256 -#define MOD_CHUNK_OPTIMUM_AREA 256 -#define GEN_CHUNK_OPTIMUM_AREA 256 - -static const unsigned short badgen[] = { - Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 -}; - -static const unsigned short badpgen[] = { - Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass, - Gen_OverrideRootKey, 0 -}; - -/* close SoundFont file and delete a SoundFont structure */ -void -sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs) -{ - fluid_list_t *p, *p2; - - if (sf->sffd) - fcbs->fclose (sf->sffd); - - if (sf->fname) - free (sf->fname); - - p = sf->info; - while (p) - { - free (p->data); - p = fluid_list_next (p); - } - delete_fluid_list(sf->info); - sf->info = NULL; - - p = sf->preset; - while (p) - { /* loop over presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* loop over preset's zones */ - sfont_free_zone (p2->data); - p2 = fluid_list_next (p2); - } /* free preset's zone list */ - delete_fluid_list (((SFPreset *) (p->data))->zone); - FLUID_FREE (p->data); /* free preset chunk */ - p = fluid_list_next (p); - } - delete_fluid_list (sf->preset); - sf->preset = NULL; - - p = sf->inst; - while (p) - { /* loop over instruments */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* loop over inst's zones */ - sfont_free_zone (p2->data); - p2 = fluid_list_next (p2); - } /* free inst's zone list */ - delete_fluid_list (((SFInst *) (p->data))->zone); - 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) */ -void -sfont_free_zone (SFZone * zone) -{ - fluid_list_t *p; - - if (!zone) - return; - - p = zone->gen; - while (p) - { /* Free gen chunks for this zone */ - if (p->data) - FLUID_FREE (p->data); - p = fluid_list_next (p); - } - delete_fluid_list (zone->gen); /* free genlist */ - - p = zone->mod; - while (p) - { /* Free mod chunks for this zone */ - if (p->data) - FLUID_FREE (p->data); - p = fluid_list_next (p); - } - delete_fluid_list (zone->mod); /* free modlist */ - - FLUID_FREE (zone); /* free zone chunk */ -} - -/* preset sort function, first by bank, then by preset # */ -int -sfont_preset_compare_func (void* a, void* b) -{ - int aval, bval; - - aval = (int) (((SFPreset *) a)->bank) << 16 | ((SFPreset *) a)->prenum; - bval = (int) (((SFPreset *) b)->bank) << 16 | ((SFPreset *) b)->prenum; - - return (aval - bval); -} - -/* delete zone from zone list */ -void -sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone) -{ - *zlist = fluid_list_remove (*zlist, (void*) zone); - sfont_free_zone (zone); -} - -/* Find generator in gen list */ -fluid_list_t * -gen_inlist (int gen, fluid_list_t * genlist) -{ /* is generator in gen list? */ - fluid_list_t *p; - - p = genlist; - while (p) - { - if (p->data == NULL) - return (NULL); - if (gen == ((SFGen *) p->data)->id) - break; - p = fluid_list_next (p); - } - return (p); -} - -/* check validity of instrument generator */ -int -gen_valid (int gen) -{ /* is generator id valid? */ - int i = 0; - - if (gen > Gen_MaxValid) - return (FALSE); - while (badgen[i] && badgen[i] != gen) - i++; - return (badgen[i] == 0); -} - -/* check validity of preset generator */ -int -gen_validp (int gen) -{ /* is preset generator valid? */ - int i = 0; - - if (!gen_valid (gen)) - return (FALSE); - while (badpgen[i] && badpgen[i] != (unsigned short) gen) - i++; - return (badpgen[i] == 0); -} - -/*================================util.c===========================*/ - -/* Logging function, returns FAIL to use as a return value in calling funcs */ -int -gerr (int ev, char * fmt, ...) -{ - va_list args; - - va_start (args, fmt); - vprintf(fmt, args); - va_end (args); - - printf("\n"); - - return (FAIL); -} diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 2e055938..a88a1c9b 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -27,18 +27,13 @@ #include "fluidsynth.h" #include "fluidsynth_priv.h" +#include "fluid_sf2.h" #include "fluid_list.h" #include "fluid_mod.h" #include "fluid_gen.h" -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - /*-----------------------------------sfont.h----------------------------*/ #define SF_SAMPMODES_LOOP 1 @@ -49,292 +44,6 @@ #define SF_MIN_SAMPLE_LENGTH 32 -/* Sound Font structure defines */ - -typedef struct _SFVersion -{ /* version structure */ - unsigned short major; - unsigned short minor; -} -SFVersion; - -typedef struct _SFMod -{ /* Modulator structure */ - unsigned short src; /* source modulator */ - unsigned short dest; /* destination generator */ - signed short amount; /* signed, degree of modulation */ - unsigned short amtsrc; /* second source controls amnt of first */ - unsigned short trans; /* transform applied to source */ -} -SFMod; - -typedef union _SFGenAmount -{ /* Generator amount structure */ - signed short sword; /* signed 16 bit value */ - unsigned short uword; /* unsigned 16 bit value */ - struct - { - unsigned char lo; /* low value for ranges */ - unsigned char hi; /* high value for ranges */ - } - range; -} -SFGenAmount; - -typedef struct _SFGen -{ /* Generator structure */ - unsigned short id; /* generator ID */ - SFGenAmount amount; /* generator value */ -} -SFGen; - -typedef struct _SFZone -{ /* Sample/instrument zone structure */ - fluid_list_t *instsamp; /* instrument/sample pointer for zone */ - fluid_list_t *gen; /* list of generators */ - fluid_list_t *mod; /* list of modulators */ -} -SFZone; - -typedef struct _SFSample -{ /* Sample structure */ - char name[21]; /* Name of sample */ - unsigned char samfile; /* Loaded sfont/sample buffer = 0/1 */ - unsigned int start; /* Offset in sample area to start of sample */ - unsigned int end; /* Offset from start to end of sample, - this is the last point of the - sample, the SF spec has this as the - 1st point after, corrected on - load/save */ - unsigned int loopstart; /* Offset from start to start of loop */ - unsigned int loopend; /* Offset from start to end of loop, - marks the first point after loop, - whose sample value is ideally - equivalent to loopstart */ - unsigned int samplerate; /* Sample rate recorded at */ - unsigned char origpitch; /* root midi key number */ - signed char pitchadj; /* pitch correction in cents */ - unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ - fluid_sample_t *fluid_sample; /* Imported sample (fixed up in fluid_defsfont_load) */ -} -SFSample; - -typedef struct _SFInst -{ /* Instrument structure */ - char name[21]; /* Name of instrument */ - fluid_list_t *zone; /* list of instrument zones */ -} -SFInst; - -typedef struct _SFPreset -{ /* Preset structure */ - char name[21]; /* preset name */ - unsigned short prenum; /* preset number */ - unsigned short bank; /* bank number */ - unsigned int libr; /* Not used (preserved) */ - unsigned int genre; /* Not used (preserved) */ - unsigned int morph; /* Not used (preserved) */ - fluid_list_t *zone; /* list of preset zones */ -} -SFPreset; - -/* NOTE: sffd is also used to determine if sound font is new (NULL) */ -typedef struct _SFData -{ /* Sound font data structure */ - SFVersion version; /* sound font version */ - SFVersion romver; /* ROM version */ - - unsigned int samplepos; /* position within sffd of the sample chunk */ - unsigned int samplesize; /* length within sffd of the sample chunk */ - - unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */ - unsigned int sample24size; /* length within sffd of the sm24 chunk */ - - char *fname; /* file name */ - FILE *sffd; /* loaded sfont file descriptor */ - 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 */ - fluid_list_t *sample; /* linked list of sample info */ -} -SFData; - -/* sf file chunk IDs */ -enum -{ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, - INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */ - - IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */ - IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */ - ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */ - - SNAM_ID, SMPL_ID, /* sample ids */ - PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ - IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ - SHDR_ID, /* sample info */ - SM24_ID -}; - -/* generator types */ -typedef enum -{ Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch, - Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ, - Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs, - Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan, - Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq, - Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay, - Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold, - Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack, - Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease, - Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument, - Gen_Reserved1, Gen_KeyRange, Gen_VelRange, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs, - Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes, - Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey, - Gen_Dummy -} -Gen_Type; - -#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ -#define Gen_Count Gen_Dummy /* count of generators */ -#define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ - -/* generator unit type */ -typedef enum -{ - None, /* No unit type */ - Unit_Smpls, /* in samples */ - Unit_32kSmpls, /* in 32k samples */ - Unit_Cent, /* in cents (1/100th of a semitone) */ - Unit_HzCent, /* in Hz Cents */ - Unit_TCent, /* in Time Cents */ - Unit_cB, /* in centibels (1/100th of a decibel) */ - Unit_Percent, /* in percentage */ - Unit_Semitone, /* in semitones */ - Unit_Range /* a range of values */ -} -Gen_Unit; - -/* functions */ -void sfont_init_chunks (void); - -void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs); -void sfont_free_zone (SFZone * zone); -int sfont_preset_compare_func (void* a, void* b); - -void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone); - -fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist); -int gen_valid (int gen); -int gen_validp (int gen); - - -/*-----------------------------------sffile.h----------------------------*/ -/* - File structures and routines (used to be in sffile.h) -*/ - -#define CHNKIDSTR(id) &idlist[(id - 1) * 4] - -/* sfont file chunk sizes */ -#define SFPHDRSIZE 38 -#define SFBAGSIZE 4 -#define SFMODSIZE 10 -#define SFGENSIZE 4 -#define SFIHDRSIZE 22 -#define SFSHDRSIZE 46 - -/* sfont file data structures */ -typedef struct _SFChunk -{ /* RIFF file chunk structure */ - unsigned int id; /* chunk id */ - unsigned int size; /* size of the following chunk */ -} -SFChunk; - -typedef struct _SFPhdr -{ - unsigned char name[20]; /* preset name */ - unsigned short preset; /* preset number */ - unsigned short bank; /* bank number */ - unsigned short pbagndx; /* index into preset bag */ - unsigned int library; /* just for preserving them */ - unsigned int genre; /* Not used */ - unsigned int morphology; /* Not used */ -} -SFPhdr; - -typedef struct _SFBag -{ - unsigned short genndx; /* index into generator list */ - unsigned short modndx; /* index into modulator list */ -} -SFBag; - -typedef struct _SFIhdr -{ - char name[20]; /* Name of instrument */ - unsigned short ibagndx; /* Instrument bag index */ -} -SFIhdr; - -typedef struct _SFShdr -{ /* Sample header loading struct */ - char name[20]; /* Sample name */ - unsigned int start; /* Offset to start of sample */ - unsigned int end; /* Offset to end of sample */ - unsigned int loopstart; /* Offset to start of loop */ - unsigned int loopend; /* Offset to end of loop */ - unsigned int samplerate; /* Sample rate recorded at */ - unsigned char origpitch; /* root midi key number */ - signed char pitchadj; /* pitch correction in cents */ - unsigned short samplelink; /* Not used */ - unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ -} -SFShdr; - -/* functions */ -SFData *sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs); - - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - -/*-----------------------------------util.h----------------------------*/ -/* - Utility functions (formerly in util.h) - */ -#define FAIL 0 -#define OK 1 - -enum -{ ErrWarn, ErrFatal, ErrStatus, ErrCorr, ErrEof, ErrMem, Errno, - ErrRead, ErrWrite -}; - -#define ErrMax ErrWrite -#define ErrnoStart Errno -#define ErrnoEnd ErrWrite - -int gerr (int ev, char * fmt, ...); - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - - /*************************************************************** * * FORWARD DECLARATIONS diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c new file mode 100644 index 00000000..82bc2f42 --- /dev/null +++ b/src/sfloader/fluid_sf2.c @@ -0,0 +1,1652 @@ +/* FluidSynth - A Software Synthesizer + * + * Copyright (C) 2003 Peter Hanappe and others. + * + * SoundFont file loading code borrowed from Smurf SoundFont Editor + * Copyright (C) 1999-2001 Josh Green + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + + +#include "fluid_sys.h" +#include "fluid_sfont.h" +#include "fluid_sf2.h" + +/*=================================sfload.c======================== + Borrowed from Smurf SoundFont Editor by Josh Green + =================================================================*/ + +/* + functions for loading data from sfont files, with appropriate byte swapping + on big endian machines. Sfont IDs are not swapped because the ID read is + equivalent to the matching ID list in memory regardless of LE/BE machine +*/ + +#define READCHUNK(var,fd, fcbs) do { \ + if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ + return(FAIL); \ + ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \ +} while(0) + +#define READD(var,fd, fcbs) do { \ + uint32_t _temp; \ + if (fcbs->fread(&_temp, 4, fd) == FLUID_FAILED) \ + return(FAIL); \ + var = FLUID_LE32TOH(_temp); \ +} while(0) + +#define READW(var,fd, fcbs) do { \ + uint16_t _temp; \ + if (fcbs->fread(&_temp, 2, fd) == FLUID_FAILED) \ + return(FAIL); \ + var = FLUID_LE16TOH(_temp); \ +} while(0) + +#define READID(var,fd, fcbs) do { \ + if (fcbs->fread(var, 4, fd) == FLUID_FAILED) \ + return(FAIL); \ +} while(0) + +#define READSTR(var,fd, fcbs) do { \ + if (fcbs->fread(var, 20, fd) == FLUID_FAILED) \ + return(FAIL); \ + (*var)[20] = '\0'; \ +} while(0) + +#define READB(var,fd, fcbs) do { \ + if (fcbs->fread(&var, 1, fd) == FLUID_FAILED) \ + return(FAIL); \ +} while(0) + +#define FSKIP(size,fd, fcbs) do { \ + if (fcbs->fseek(fd, size, SEEK_CUR) == FLUID_FAILED) \ + return(FAIL); \ +} while(0) + +#define FSKIPW(fd, fcbs) do { \ + if (fcbs->fseek(fd, 2, SEEK_CUR) == FLUID_FAILED) \ + return(FAIL); \ +} while(0) + +/* removes and advances a fluid_list_t pointer */ +#define SLADVREM(list, item) do { \ + fluid_list_t *_temp = item; \ + item = fluid_list_next(item); \ + list = fluid_list_remove_link(list, _temp); \ + delete1_fluid_list(_temp); \ +} while(0) + +static int chunkid (unsigned int id); +static int load_body (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int read_listchunk (SFChunk * chunk, void * fd, const fluid_file_callbacks_t* fcbs); +static int process_info (int size, SFData * sf, void* fd, const fluid_file_callbacks_t* fcbs); +static int process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, + int * size, void * fd, const fluid_file_callbacks_t* fcbs); +static int process_pdta (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_phdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_pbag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_pgen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_ihdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_ibag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_imod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_igen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int load_shdr (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); +static int fixup_pgen (SFData * sf); +static int fixup_igen (SFData * sf); +static int fixup_sample (SFData * sf); + +static const char idlist[] = { + "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" + "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24" +}; + +/* sound font file load functions */ +static int +chunkid (unsigned int id) +{ + unsigned int i; + unsigned int *p; + + p = (unsigned int *) & idlist; + for (i = 0; i < sizeof (idlist) / sizeof (int); i++, p += 1) + if (*p == id) + return (i + 1); + + return (UNKN_ID); +} + +SFData * +sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs) +{ + SFData *sf = NULL; + void *fd; + int fsize = 0; + int err = FALSE; + + if ((fd = fcbs->fopen (fname)) == NULL) + { + FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname); + return (NULL); + } + + if (!(sf = FLUID_NEW (SFData))) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + fclose(fd); + err = TRUE; + } + + if (!err) + { + memset (sf, 0, sizeof (SFData)); /* zero sfdata */ + sf->fname = FLUID_STRDUP (fname); /* copy file name */ + sf->sffd = fd; + } + + /* get size of file */ + if (!err && fcbs->fseek (fd, 0L, SEEK_END) == FLUID_FAILED) + { /* seek to end of file */ + err = TRUE; + FLUID_LOG (FLUID_ERR, _("Seek to end of file failed")); + } + if (!err && (fsize = fcbs->ftell (fd)) == FLUID_FAILED) + { /* position = size */ + err = TRUE; + FLUID_LOG (FLUID_ERR, _("Get end of file position failed")); + } + if (!err) + rewind (fd); + + if (!err && !load_body (fsize, sf, fd, fcbs)) + err = TRUE; /* load the sfont */ + + if (err) + { + if (sf) + sfont_close (sf, fcbs); + return (NULL); + } + + return (sf); +} + +static int +load_body (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + SFChunk chunk; + + READCHUNK (&chunk, fd, fcbs); /* load RIFF chunk */ + if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */ + FLUID_LOG (FLUID_ERR, _("Not a RIFF file")); + return (FAIL); + } + + READID (&chunk.id, fd, fcbs); /* load file ID */ + if (chunkid (chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ + FLUID_LOG (FLUID_ERR, _("Not a SoundFont file")); + return (FAIL); + } + + if (chunk.size != size - 8) { + gerr (ErrCorr, _("SoundFont file size mismatch")); + return (FAIL); + } + + /* Process INFO block */ + if (!read_listchunk (&chunk, fd, fcbs)) + return (FAIL); + if (chunkid (chunk.id) != INFO_ID) + return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk"))); + if (!process_info (chunk.size, sf, fd, fcbs)) + return (FAIL); + + /* Process sample chunk */ + if (!read_listchunk (&chunk, fd, fcbs)) + return (FAIL); + if (chunkid (chunk.id) != SDTA_ID) + return (gerr (ErrCorr, + _("Invalid ID found when expecting SAMPLE chunk"))); + if (!process_sdta (chunk.size, sf, fd, fcbs)) + return (FAIL); + + /* process HYDRA chunk */ + if (!read_listchunk (&chunk, fd, fcbs)) + return (FAIL); + if (chunkid (chunk.id) != PDTA_ID) + return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk"))); + if (!process_pdta (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!fixup_pgen (sf)) + return (FAIL); + if (!fixup_igen (sf)) + return (FAIL); + if (!fixup_sample (sf)) + return (FAIL); + + /* sort preset list by bank, preset # */ + sf->preset = fluid_list_sort (sf->preset, + (fluid_compare_func_t) sfont_preset_compare_func); + + return (OK); +} + +static int +read_listchunk (SFChunk * chunk, void * fd, const fluid_file_callbacks_t* fcbs) +{ + READCHUNK (chunk, fd, fcbs); /* read list chunk */ + if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */ + return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse"))); + READID (&chunk->id, fd, fcbs); /* read id string */ + chunk->size -= 4; + return (OK); +} + +static int +process_info (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + SFChunk chunk; + unsigned char id; + char *item; + unsigned short ver; + + while (size > 0) + { + READCHUNK (&chunk, fd, fcbs); + size -= 8; + + id = chunkid (chunk.id); + + if (id == IFIL_ID) + { /* sound font version chunk? */ + if (chunk.size != 4) + return (gerr (ErrCorr, + _("Sound font version info chunk has invalid size"))); + + READW (ver, fd, fcbs); + sf->version.major = ver; + READW (ver, fd, fcbs); + sf->version.minor = ver; + + if (sf->version.major < 2) { + FLUID_LOG (FLUID_ERR, + _("Sound font version is %d.%d which is not" + " supported, convert to version 2.0x"), + sf->version.major, + sf->version.minor); + return (FAIL); + } + + if (sf->version.major == 3) { +#if !LIBSNDFILE_SUPPORT + FLUID_LOG (FLUID_WARN, + _("Sound font version is %d.%d but fluidsynth was compiled without" + " support for (v3.x)"), + sf->version.major, + sf->version.minor); + return (FAIL); +#endif + } + else if (sf->version.major > 2) { + FLUID_LOG (FLUID_WARN, + _("Sound font version is %d.%d which is newer than" + " what this version of fluidsynth was designed for (v2.0x)"), + sf->version.major, + sf->version.minor); + return (FAIL); + } + } + else if (id == IVER_ID) + { /* ROM version chunk? */ + if (chunk.size != 4) + return (gerr (ErrCorr, + _("ROM version info chunk has invalid size"))); + + READW (ver, fd, fcbs); + sf->romver.major = ver; + READW (ver, fd, fcbs); + sf->romver.minor = ver; + } + else if (id != UNKN_ID) + { + if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) + || (chunk.size % 2)) + return (gerr (ErrCorr, + _("INFO sub chunk %.4s has invalid chunk size" + " of %d bytes"), &chunk.id, chunk.size)); + + /* alloc for chunk id and da chunk */ + 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); + + *(unsigned char *) item = id; + if (fcbs->fread(&item[1], chunk.size, fd) == FLUID_FAILED) + return (FAIL); + + /* force terminate info item (don't forget uint8 info ID) */ + *(item + chunk.size) = '\0'; + } + else + return (gerr (ErrCorr, _("Invalid chunk id in INFO chunk"))); + size -= chunk.size; + } + + if (size < 0) + return (gerr (ErrCorr, _("INFO chunk size mismatch"))); + + return (OK); +} + +static int +process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + SFChunk chunk; + + if (size == 0) + return (OK); /* no sample data? */ + + /* read sub chunk */ + READCHUNK (&chunk, fd, fcbs); + size -= 8; + + if (chunkid (chunk.id) != SMPL_ID) + return (gerr (ErrCorr, + _("Expected SMPL chunk found invalid id instead"))); + + /* SDTA chunk may also contain sm24 chunk for 24 bit samples + * (not yet supported), only an error if SMPL chunk size is + * greater than SDTA. */ + if (chunk.size > size) + return (gerr (ErrCorr, _("SDTA chunk size mismatch"))); + + /* sample data follows */ + sf->samplepos = fcbs->ftell (fd); + + /* used in fixup_sample() to check validity of sample headers */ + sf->samplesize = chunk.size; + + FSKIP (chunk.size, fd, fcbs); + size -= chunk.size; + + if(sf->version.major >= 2 && sf->version.minor >= 4) + { + /* any chance to find another chunk here? */ + if(size > 8) + { + /* read sub chunk */ + READCHUNK (&chunk, fd, fcbs); + size -= 8; + + if (chunkid (chunk.id) == SM24_ID) + { + int sm24size, sdtahalfsize; + + FLUID_LOG(FLUID_DBG, "Found SM24 chunk"); + if (chunk.size > size) + { + FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24"); + goto ret; // no error + } + + sdtahalfsize = sf->samplesize/2; + /* + 1 byte in the case that half the size of smpl chunk is an odd value */ + sdtahalfsize += sdtahalfsize%2; + sm24size = chunk.size; + + if (sdtahalfsize != sm24size) + { + FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != 0x%X), ignoring SM24", sm24size, sdtahalfsize); + goto ret; // no error + } + + /* sample data24 follows */ + sf->sample24pos = fcbs->ftell (fd); + sf->sample24size = sm24size; + } + } + } + +ret: + FSKIP (size, fd, fcbs); + + return (OK); +} + +static int +pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, + int * size, void * fd, const fluid_file_callbacks_t* fcbs) +{ + unsigned int id; + const char *expstr; + + expstr = CHNKIDSTR (expid); /* in case we need it */ + + READCHUNK (chunk, fd, fcbs); + *size -= 8; + + if ((id = chunkid (chunk->id)) != expid) + return (gerr (ErrCorr, _("Expected" + " PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr)); + + if (chunk->size % reclen) /* valid chunk size? */ + return (gerr (ErrCorr, + _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, + reclen)); + if ((*size -= chunk->size) < 0) + return (gerr (ErrCorr, + _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr)); + return (OK); +} + +static int +process_pdta (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + SFChunk chunk; + + if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_phdr (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_pbag (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_pmod (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_pgen (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_ihdr (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_ibag (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_imod (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_igen (chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_shdr (chunk.size, sf, fd, fcbs)) + return (FAIL); + + return (OK); +} + +/* preset header loader */ +static int +load_phdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + int i, i2; + SFPreset *p, *pr = NULL; /* ptr to current & previous preset */ + unsigned short zndx, pzndx = 0; + + if (size % SFPHDRSIZE || size == 0) + return (gerr (ErrCorr, _("Preset header chunk size is invalid"))); + + i = size / SFPHDRSIZE - 1; + if (i == 0) + { /* at least one preset + term record */ + FLUID_LOG (FLUID_WARN, _("File contains no presets")); + FSKIP (SFPHDRSIZE, fd, fcbs); + return (OK); + } + + for (; i > 0; i--) + { /* load all preset headers */ + p = FLUID_NEW (SFPreset); + sf->preset = fluid_list_append (sf->preset, p); + p->zone = NULL; /* In case of failure, sfont_close can cleanup */ + READSTR (&p->name, fd, fcbs); /* possible read failure ^ */ + READW (p->prenum, fd, fcbs); + READW (p->bank, fd, fcbs); + READW (zndx, fd, fcbs); + READD (p->libr, fd, fcbs); + READD (p->genre, fd, fcbs); + READD (p->morph, fd, fcbs); + + if (pr) + { /* not first preset? */ + if (zndx < pzndx) + return (gerr (ErrCorr, _("Preset header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + { + pr->zone = fluid_list_prepend (pr->zone, NULL); + } + } + else if (zndx > 0) /* 1st preset, warn if ofs >0 */ + FLUID_LOG (FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx); + pr = p; /* update preset ptr */ + pzndx = zndx; + } + + FSKIP (24, fd, fcbs); + READW (zndx, fd, fcbs); /* Read terminal generator index */ + FSKIP (12, fd, fcbs); + + if (zndx < pzndx) + return (gerr (ErrCorr, _("Preset header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + { + pr->zone = fluid_list_prepend (pr->zone, NULL); + } + + return (OK); +} + +/* preset bag loader */ +static int +load_pbag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2; + SFZone *z, *pz = NULL; + unsigned short genndx, modndx; + unsigned short pgenndx = 0, pmodndx = 0; + unsigned short i; + + if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ + return (gerr (ErrCorr, _("Preset bag chunk size is invalid"))); + + p = sf->preset; + while (p) + { /* traverse through presets */ + p2 = ((SFPreset *) (p->data))->zone; + while (p2) + { /* traverse preset's zones */ + if ((size -= SFBAGSIZE) < 0) + return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); + z = FLUID_NEW (SFZone); + p2->data = z; + z->gen = NULL; /* Init gen and mod before possible failure, */ + z->mod = NULL; /* to ensure proper cleanup (sfont_close) */ + READW (genndx, fd, fcbs); /* possible read failure ^ */ + READW (modndx, fd, fcbs); + z->instsamp = NULL; + + if (pz) + { /* if not first zone */ + if (genndx < pgenndx) + return (gerr (ErrCorr, + _("Preset bag generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr (ErrCorr, + _("Preset bag modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend (pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend (pz->mod, NULL); + } + pz = z; /* update previous zone ptr */ + pgenndx = genndx; /* update previous zone gen index */ + pmodndx = modndx; /* update previous zone mod index */ + p2 = fluid_list_next (p2); + } + p = fluid_list_next (p); + } + + size -= SFBAGSIZE; + if (size != 0) + return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); + + READW (genndx, fd, fcbs); + READW (modndx, fd, fcbs); + + if (!pz) + { + if (genndx > 0) + FLUID_LOG (FLUID_WARN, _("No preset generators and terminal index not 0")); + if (modndx > 0) + FLUID_LOG (FLUID_WARN, _("No preset modulators and terminal index not 0")); + return (OK); + } + + if (genndx < pgenndx) + return (gerr (ErrCorr, _("Preset bag generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr (ErrCorr, _("Preset bag modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend (pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend (pz->mod, NULL); + + return (OK); +} + +/* preset modulator loader */ +static int +load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2, *p3; + SFMod *m; + + p = sf->preset; + while (p) + { /* traverse through all presets */ + p2 = ((SFPreset *) (p->data))->zone; + while (p2) + { /* traverse this preset's zones */ + p3 = ((SFZone *) (p2->data))->mod; + while (p3) + { /* load zone's modulators */ + if ((size -= SFMODSIZE) < 0) + return (gerr (ErrCorr, + _("Preset modulator chunk size mismatch"))); + m = FLUID_NEW (SFMod); + p3->data = m; + READW (m->src, fd, fcbs); + READW (m->dest, fd, fcbs); + READW (m->amount, fd, fcbs); + READW (m->amtsrc, fd, fcbs); + READW (m->trans, fd, fcbs); + p3 = fluid_list_next (p3); + } + p2 = fluid_list_next (p2); + } + p = fluid_list_next (p); + } + + /* + If there isn't even a terminal record + Hmmm, the specs say there should be one, but.. + */ + if (size == 0) + return (OK); + + size -= SFMODSIZE; + if (size != 0) + return (gerr (ErrCorr, _("Preset modulator chunk size mismatch"))); + FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */ + + return (OK); +} + +/* ------------------------------------------------------------------- + * preset generator loader + * generator (per preset) loading rules: + * Zones with no generators or modulators shall be annihilated + * Global zone must be 1st zone, discard additional ones (instrumentless zones) + * + * generator (per zone) loading rules (in order of decreasing precedence): + * KeyRange is 1st in list (if exists), else discard + * if a VelRange exists only preceded by a KeyRange, else discard + * if a generator follows an instrument discard it + * if a duplicate generator exists replace previous one + * ------------------------------------------------------------------- */ +static int +load_pgen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; + SFZone *z; + SFGen *g; + SFGenAmount genval; + unsigned short genid; + int level, skip, drop, gzone, discarded; + + p = sf->preset; + while (p) + { /* traverse through all presets */ + gzone = FALSE; + discarded = FALSE; + p2 = ((SFPreset *) (p->data))->zone; + if (p2) + hz = &p2; + while (p2) + { /* traverse preset's zones */ + level = 0; + z = (SFZone *) (p2->data); + p3 = z->gen; + while (p3) + { /* load zone's generators */ + dup = NULL; + skip = FALSE; + drop = FALSE; + if ((size -= SFGENSIZE) < 0) + return (gerr (ErrCorr, + _("Preset generator chunk size mismatch"))); + + READW (genid, fd, fcbs); + + if (genid == Gen_KeyRange) + { /* nothing precedes */ + if (level == 0) + { + level = 1; + READB (genval.range.lo, fd, fcbs); + READB (genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_VelRange) + { /* only KeyRange precedes */ + if (level <= 1) + { + level = 2; + READB (genval.range.lo, fd, fcbs); + READB (genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_Instrument) + { /* inst is last gen */ + level = 3; + READW (genval.uword, fd, fcbs); + ((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1); + break; /* break out of generator loop */ + } + else + { + level = 2; + if (gen_validp (genid)) + { /* generator valid? */ + READW (genval.sword, fd, fcbs); + dup = gen_inlist (genid, z->gen); + } + else + skip = TRUE; + } + + if (!skip) + { + if (!dup) + { /* if gen ! dup alloc new */ + g = FLUID_NEW (SFGen); + p3->data = g; + g->id = genid; + } + else + { + g = (SFGen *) (dup->data); /* ptr to orig gen */ + drop = TRUE; + } + g->amount = genval; + } + else + { /* Skip this generator */ + discarded = TRUE; + drop = TRUE; + FSKIPW (fd, fcbs); + } + + if (!drop) + p3 = fluid_list_next (p3); /* next gen */ + else + SLADVREM (z->gen, p3); /* drop place holder */ + + } /* generator loop */ + + if (level == 3) + SLADVREM (z->gen, p3); /* zone has inst? */ + else + { /* congratulations its a global zone */ + if (!gzone) + { /* Prior global zones? */ + gzone = TRUE; + + /* if global zone is not 1st zone, relocate */ + if (*hz != p2) + { + void* save = p2->data; + FLUID_LOG (FLUID_WARN, + _("Preset \"%s\": Global zone is not first zone"), + ((SFPreset *) (p->data))->name); + SLADVREM (*hz, p2); + *hz = fluid_list_prepend (*hz, save); + continue; + } + } + else + { /* previous global zone exists, discard */ + FLUID_LOG (FLUID_WARN, + _("Preset \"%s\": Discarding invalid global zone"), + ((SFPreset *) (p->data))->name); + sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); + } + } + + while (p3) + { /* Kill any zones following an instrument */ + discarded = TRUE; + if ((size -= SFGENSIZE) < 0) + return (gerr (ErrCorr, + _("Preset generator chunk size mismatch"))); + FSKIP (SFGENSIZE, fd, fcbs); + SLADVREM (z->gen, p3); + } + + p2 = fluid_list_next (p2); /* next zone */ + } + if (discarded) + FLUID_LOG(FLUID_WARN, + _("Preset \"%s\": Some invalid generators were discarded"), + ((SFPreset *) (p->data))->name); + p = fluid_list_next (p); + } + + /* in case there isn't a terminal record */ + if (size == 0) + return (OK); + + size -= SFGENSIZE; + if (size != 0) + return (gerr (ErrCorr, _("Preset generator chunk size mismatch"))); + FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */ + + return (OK); +} + +/* instrument header loader */ +static int +load_ihdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + int i, i2; + SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ + unsigned short zndx, pzndx = 0; + + if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ + return (gerr (ErrCorr, _("Instrument header has invalid size"))); + + size = size / SFIHDRSIZE - 1; + if (size == 0) + { /* at least one preset + term record */ + FLUID_LOG (FLUID_WARN, _("File contains no instruments")); + FSKIP (SFIHDRSIZE, fd, fcbs); + return (OK); + } + + for (i = 0; i < size; i++) + { /* load all instrument headers */ + p = FLUID_NEW (SFInst); + sf->inst = fluid_list_append (sf->inst, p); + p->zone = NULL; /* For proper cleanup if fail (sfont_close) */ + READSTR (&p->name, fd, fcbs); /* Possible read failure ^ */ + READW (zndx, fd, fcbs); + + if (pr) + { /* not first instrument? */ + if (zndx < pzndx) + return (gerr (ErrCorr, + _("Instrument header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + pr->zone = fluid_list_prepend (pr->zone, NULL); + } + else if (zndx > 0) /* 1st inst, warn if ofs >0 */ + FLUID_LOG (FLUID_WARN, _("%d instrument zones not referenced, discarding"), + zndx); + pzndx = zndx; + pr = p; /* update instrument ptr */ + } + + FSKIP (20, fd, fcbs); + READW (zndx, fd, fcbs); + + if (zndx < pzndx) + return (gerr (ErrCorr, _("Instrument header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + pr->zone = fluid_list_prepend (pr->zone, NULL); + + return (OK); +} + +/* instrument bag loader */ +static int +load_ibag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2; + SFZone *z, *pz = NULL; + unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0; + int i; + + if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ + return (gerr (ErrCorr, _("Instrument bag chunk size is invalid"))); + + p = sf->inst; + while (p) + { /* traverse through inst */ + p2 = ((SFInst *) (p->data))->zone; + while (p2) + { /* load this inst's zones */ + if ((size -= SFBAGSIZE) < 0) + return (gerr (ErrCorr, _("Instrument bag chunk size mismatch"))); + z = FLUID_NEW (SFZone); + p2->data = z; + z->gen = NULL; /* In case of failure, */ + z->mod = NULL; /* sfont_close can clean up */ + READW (genndx, fd, fcbs); /* READW = possible read failure */ + READW (modndx, fd, fcbs); + z->instsamp = NULL; + + if (pz) + { /* if not first zone */ + if (genndx < pgenndx) + return (gerr (ErrCorr, + _("Instrument generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr (ErrCorr, + _("Instrument modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend (pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend (pz->mod, NULL); + } + pz = z; /* update previous zone ptr */ + pgenndx = genndx; + pmodndx = modndx; + p2 = fluid_list_next (p2); + } + p = fluid_list_next (p); + } + + size -= SFBAGSIZE; + if (size != 0) + return (gerr (ErrCorr, _("Instrument chunk size mismatch"))); + + READW (genndx, fd, fcbs); + READW (modndx, fd, fcbs); + + if (!pz) + { /* in case that all are no zoners */ + if (genndx > 0) + FLUID_LOG (FLUID_WARN, + _("No instrument generators and terminal index not 0")); + if (modndx > 0) + FLUID_LOG (FLUID_WARN, + _("No instrument modulators and terminal index not 0")); + return (OK); + } + + if (genndx < pgenndx) + return (gerr (ErrCorr, _("Instrument generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr (ErrCorr, _("Instrument modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend (pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend (pz->mod, NULL); + + return (OK); +} + +/* instrument modulator loader */ +static int +load_imod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2, *p3; + SFMod *m; + + p = sf->inst; + while (p) + { /* traverse through all inst */ + p2 = ((SFInst *) (p->data))->zone; + while (p2) + { /* traverse this inst's zones */ + p3 = ((SFZone *) (p2->data))->mod; + while (p3) + { /* load zone's modulators */ + if ((size -= SFMODSIZE) < 0) + return (gerr (ErrCorr, + _("Instrument modulator chunk size mismatch"))); + m = FLUID_NEW (SFMod); + p3->data = m; + READW (m->src, fd, fcbs); + READW (m->dest, fd, fcbs); + READW (m->amount, fd, fcbs); + READW (m->amtsrc, fd, fcbs); + READW (m->trans, fd, fcbs); + p3 = fluid_list_next (p3); + } + p2 = fluid_list_next (p2); + } + p = fluid_list_next (p); + } + + /* + If there isn't even a terminal record + Hmmm, the specs say there should be one, but.. + */ + if (size == 0) + return (OK); + + size -= SFMODSIZE; + if (size != 0) + return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch"))); + FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */ + + return (OK); +} + +/* load instrument generators (see load_pgen for loading rules) */ +static int +load_igen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; + SFZone *z; + SFGen *g; + SFGenAmount genval; + unsigned short genid; + int level, skip, drop, gzone, discarded; + + p = sf->inst; + while (p) + { /* traverse through all instruments */ + gzone = FALSE; + discarded = FALSE; + p2 = ((SFInst *) (p->data))->zone; + if (p2) + hz = &p2; + while (p2) + { /* traverse this instrument's zones */ + level = 0; + z = (SFZone *) (p2->data); + p3 = z->gen; + while (p3) + { /* load zone's generators */ + dup = NULL; + skip = FALSE; + drop = FALSE; + if ((size -= SFGENSIZE) < 0) + return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); + + READW (genid, fd, fcbs); + + if (genid == Gen_KeyRange) + { /* nothing precedes */ + if (level == 0) + { + level = 1; + READB (genval.range.lo, fd, fcbs); + READB (genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_VelRange) + { /* only KeyRange precedes */ + if (level <= 1) + { + level = 2; + READB (genval.range.lo, fd, fcbs); + READB (genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_SampleId) + { /* sample is last gen */ + level = 3; + READW (genval.uword, fd, fcbs); + ((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1); + break; /* break out of generator loop */ + } + else + { + level = 2; + if (gen_valid (genid)) + { /* gen valid? */ + READW (genval.sword, fd, fcbs); + dup = gen_inlist (genid, z->gen); + } + else + skip = TRUE; + } + + if (!skip) + { + if (!dup) + { /* if gen ! dup alloc new */ + g = FLUID_NEW (SFGen); + p3->data = g; + g->id = genid; + } + else + { + g = (SFGen *) (dup->data); + drop = TRUE; + } + g->amount = genval; + } + else + { /* skip this generator */ + discarded = TRUE; + drop = TRUE; + FSKIPW (fd, fcbs); + } + + if (!drop) + p3 = fluid_list_next (p3); /* next gen */ + else + SLADVREM (z->gen, p3); + + } /* generator loop */ + + if (level == 3) + SLADVREM (z->gen, p3); /* zone has sample? */ + else + { /* its a global zone */ + if (!gzone) + { + gzone = TRUE; + + /* if global zone is not 1st zone, relocate */ + if (*hz != p2) + { + void* save = p2->data; + FLUID_LOG (FLUID_WARN, + _("Instrument \"%s\": Global zone is not first zone"), + ((SFPreset *) (p->data))->name); + SLADVREM (*hz, p2); + *hz = fluid_list_prepend (*hz, save); + continue; + } + } + else + { /* previous global zone exists, discard */ + FLUID_LOG (FLUID_WARN, + _("Instrument \"%s\": Discarding invalid global zone"), + ((SFInst *) (p->data))->name); + sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); + } + } + + while (p3) + { /* Kill any zones following a sample */ + discarded = TRUE; + if ((size -= SFGENSIZE) < 0) + return (gerr (ErrCorr, + _("Instrument generator chunk size mismatch"))); + FSKIP (SFGENSIZE, fd, fcbs); + SLADVREM (z->gen, p3); + } + + p2 = fluid_list_next (p2); /* next zone */ + } + if (discarded) + FLUID_LOG(FLUID_WARN, + _("Instrument \"%s\": Some invalid generators were discarded"), + ((SFInst *) (p->data))->name); + p = fluid_list_next (p); + } + + /* for those non-terminal record cases, grr! */ + if (size == 0) + return (OK); + + size -= SFGENSIZE; + if (size != 0) + return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); + FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */ + + return (OK); +} + +/* sample header loader */ +static int +load_shdr (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +{ + unsigned int i; + SFSample *p; + + if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ + return (gerr (ErrCorr, _("Sample header has invalid size"))); + + size = size / SFSHDRSIZE - 1; + if (size == 0) + { /* at least one sample + term record? */ + FLUID_LOG (FLUID_WARN, _("File contains no samples")); + FSKIP (SFSHDRSIZE, fd, fcbs); + return (OK); + } + + /* load all sample headers */ + for (i = 0; i < size; i++) + { + p = FLUID_NEW (SFSample); + sf->sample = fluid_list_append (sf->sample, p); + READSTR (&p->name, fd, fcbs); + READD (p->start, fd, fcbs); + READD (p->end, fd, fcbs); /* - end, loopstart and loopend */ + READD (p->loopstart, fd, fcbs); /* - will be checked and turned into */ + READD (p->loopend, fd, fcbs); /* - offsets in fixup_sample() */ + READD (p->samplerate, fd, fcbs); + READB (p->origpitch, fd, fcbs); + READB (p->pitchadj, fd, fcbs); + FSKIPW (fd, fcbs); /* skip sample link */ + READW (p->sampletype, fd, fcbs); + p->samfile = 0; + } + + FSKIP (SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */ + + return (OK); +} + +/* "fixup" (inst # -> inst ptr) instrument references in preset list */ +static int +fixup_pgen (SFData * sf) +{ + fluid_list_t *p, *p2, *p3; + SFZone *z; + int i; + + p = sf->preset; + while (p) + { + p2 = ((SFPreset *) (p->data))->zone; + while (p2) + { /* traverse this preset's zones */ + z = (SFZone *) (p2->data); + if ((i = FLUID_POINTER_TO_INT (z->instsamp))) + { /* load instrument # */ + p3 = fluid_list_nth (sf->inst, i - 1); + if (!p3) + return (gerr (ErrCorr, + _("Preset %03d %03d: Invalid instrument reference"), + ((SFPreset *) (p->data))->bank, + ((SFPreset *) (p->data))->prenum)); + z->instsamp = p3; + } + else + z->instsamp = NULL; + p2 = fluid_list_next (p2); + } + p = fluid_list_next (p); + } + + return (OK); +} + +/* "fixup" (sample # -> sample ptr) sample references in instrument list */ +static int +fixup_igen (SFData * sf) +{ + fluid_list_t *p, *p2, *p3; + SFZone *z; + int i; + + p = sf->inst; + while (p) + { + p2 = ((SFInst *) (p->data))->zone; + while (p2) + { /* traverse instrument's zones */ + z = (SFZone *) (p2->data); + if ((i = FLUID_POINTER_TO_INT (z->instsamp))) + { /* load sample # */ + p3 = fluid_list_nth (sf->sample, i - 1); + if (!p3) + return (gerr (ErrCorr, + _("Instrument \"%s\": Invalid sample reference"), + ((SFInst *) (p->data))->name)); + z->instsamp = p3; + } + p2 = fluid_list_next (p2); + } + p = fluid_list_next (p); + } + + return (OK); +} + +/* convert sample end, loopstart and loopend to offsets and check if valid */ +static int +fixup_sample (SFData * sf) +{ + fluid_list_t *p; + SFSample *sam; + int invalid_loops=FALSE; + int invalid_loopstart; + int invalid_loopend, loopend_end_mismatch; + unsigned int total_bytes = sf->samplesize; + unsigned int total_samples = total_bytes / FLUID_MEMBER_SIZE(fluid_defsfont_t, sampledata[0]); + + p = sf->sample; + while (p) + { + unsigned int max_end; + + sam = (SFSample *) (p->data); + + /* Standard SoundFont files (SF2) use sample word indices for sample start and end pointers, + * but SF3 files with Ogg Vorbis compression use byte indices for start and end. */ + max_end = (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) ? total_bytes : total_samples; + + /* ROM samples are unusable for us by definition, so simply ignore them. */ + if (sam->sampletype & FLUID_SAMPLETYPE_ROM) + { + sam->start = sam->end = sam->loopstart = sam->loopend = 0; + goto next_sample; + } + + /* If end is over the sample data chunk or sam start is greater than 4 + * less than the end (at least 4 samples). + * + * FIXME: where does this number 4 come from? And do we need a different number for SF3 files? + * Maybe we should check for the minimum Ogg Vorbis headers size? */ + if ((sam->end > max_end) || (sam->start > (sam->end - 4))) + { + FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid," + " disabling and will not be saved"), sam->name); + sam->start = sam->end = sam->loopstart = sam->loopend = 0; + goto next_sample; + } + + /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop */ + invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); + /* while loopend is the first point AFTER the last sample of the loop. + * this is as it should be. however we cannot be sure whether any of sam.loopend or sam.end + * is correct. hours of thinking through this have concluded, that it would be best practice + * to mangle with loops as little as necessary by only making sure loopend is within + * max_end. incorrect soundfont shall preferably fail loudly. */ + invalid_loopend = (sam->loopend > max_end) || (sam->loopstart >= sam->loopend); + + loopend_end_mismatch = (sam->loopend > sam->end); + + if (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) + { + /* + * compressed samples get fixed up after decompression + * + * however we cant use the logic below, because uncompressed samples are stored in individual buffers + */ + } + else if (invalid_loopstart || invalid_loopend || loopend_end_mismatch) /* loop is fowled?? (cluck cluck :) */ + { + /* though illegal, loopend may be set to loopstart to disable loop */ + /* is it worth informing the user? */ + invalid_loops |= (sam->loopend != sam->loopstart); + + /* force incorrect loop points into the sample range, ignore padding */ + if(invalid_loopstart) + { + FLUID_LOG (FLUID_DBG, _("Sample '%s' has unusable loop start '%d'," + " setting to sample start at '%d'"), sam->name, sam->loopstart, sam->start); + sam->loopstart = sam->start; + } + + if(invalid_loopend) + { + FLUID_LOG (FLUID_DBG, _("Sample '%s' has unusable loop stop '%d'," + " setting to sample stop at '%d'"), sam->name, sam->loopend, sam->end); + /* since at this time sam->end points after valid sample data (will correct that few lines below), + * set loopend to that first invalid sample, since it should never be played, but instead the last + * valid sample will be played */ + sam->loopend = sam->end; + } + else if(loopend_end_mismatch) + { + FLUID_LOG (FLUID_DBG, _("Sample '%s' has invalid loop stop '%d'," + " sample stop at '%d', using it anyway"), sam->name, sam->loopend, sam->end); + } + } + + /* convert sample end, loopstart, loopend to offsets from sam->start */ + sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */ + sam->loopstart -= sam->start; + sam->loopend -= sam->start; + +next_sample: + p = fluid_list_next (p); + } + + if(invalid_loops) + { + FLUID_LOG (FLUID_WARN, _("Found samples with invalid loops, audible glitches possible.")); + } + + return (OK); +} + +/*=================================sfont.c======================== + Smurf SoundFont Editor + ================================================================*/ + + +/* optimum chunk area sizes (could be more optimum) */ +#define PRESET_CHUNK_OPTIMUM_AREA 256 +#define INST_CHUNK_OPTIMUM_AREA 256 +#define SAMPLE_CHUNK_OPTIMUM_AREA 256 +#define ZONE_CHUNK_OPTIMUM_AREA 256 +#define MOD_CHUNK_OPTIMUM_AREA 256 +#define GEN_CHUNK_OPTIMUM_AREA 256 + +static const unsigned short badgen[] = { + Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, + Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 +}; + +static const unsigned short badpgen[] = { + Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs, + Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, + Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass, + Gen_OverrideRootKey, 0 +}; + +/* close SoundFont file and delete a SoundFont structure */ +void +sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs) +{ + fluid_list_t *p, *p2; + + if (sf->sffd) + fcbs->fclose (sf->sffd); + + if (sf->fname) + free (sf->fname); + + p = sf->info; + while (p) + { + free (p->data); + p = fluid_list_next (p); + } + delete_fluid_list(sf->info); + sf->info = NULL; + + p = sf->preset; + while (p) + { /* loop over presets */ + p2 = ((SFPreset *) (p->data))->zone; + while (p2) + { /* loop over preset's zones */ + sfont_free_zone (p2->data); + p2 = fluid_list_next (p2); + } /* free preset's zone list */ + delete_fluid_list (((SFPreset *) (p->data))->zone); + FLUID_FREE (p->data); /* free preset chunk */ + p = fluid_list_next (p); + } + delete_fluid_list (sf->preset); + sf->preset = NULL; + + p = sf->inst; + while (p) + { /* loop over instruments */ + p2 = ((SFInst *) (p->data))->zone; + while (p2) + { /* loop over inst's zones */ + sfont_free_zone (p2->data); + p2 = fluid_list_next (p2); + } /* free inst's zone list */ + delete_fluid_list (((SFInst *) (p->data))->zone); + 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) */ +void +sfont_free_zone (SFZone * zone) +{ + fluid_list_t *p; + + if (!zone) + return; + + p = zone->gen; + while (p) + { /* Free gen chunks for this zone */ + if (p->data) + FLUID_FREE (p->data); + p = fluid_list_next (p); + } + delete_fluid_list (zone->gen); /* free genlist */ + + p = zone->mod; + while (p) + { /* Free mod chunks for this zone */ + if (p->data) + FLUID_FREE (p->data); + p = fluid_list_next (p); + } + delete_fluid_list (zone->mod); /* free modlist */ + + FLUID_FREE (zone); /* free zone chunk */ +} + +/* preset sort function, first by bank, then by preset # */ +int +sfont_preset_compare_func (void* a, void* b) +{ + int aval, bval; + + aval = (int) (((SFPreset *) a)->bank) << 16 | ((SFPreset *) a)->prenum; + bval = (int) (((SFPreset *) b)->bank) << 16 | ((SFPreset *) b)->prenum; + + return (aval - bval); +} + +/* delete zone from zone list */ +void +sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone) +{ + *zlist = fluid_list_remove (*zlist, (void*) zone); + sfont_free_zone (zone); +} + +/* Find generator in gen list */ +fluid_list_t * +gen_inlist (int gen, fluid_list_t * genlist) +{ /* is generator in gen list? */ + fluid_list_t *p; + + p = genlist; + while (p) + { + if (p->data == NULL) + return (NULL); + if (gen == ((SFGen *) p->data)->id) + break; + p = fluid_list_next (p); + } + return (p); +} + +/* check validity of instrument generator */ +int +gen_valid (int gen) +{ /* is generator id valid? */ + int i = 0; + + if (gen > Gen_MaxValid) + return (FALSE); + while (badgen[i] && badgen[i] != gen) + i++; + return (badgen[i] == 0); +} + +/* check validity of preset generator */ +int +gen_validp (int gen) +{ /* is preset generator valid? */ + int i = 0; + + if (!gen_valid (gen)) + return (FALSE); + while (badpgen[i] && badpgen[i] != (unsigned short) gen) + i++; + return (badpgen[i] == 0); +} + +/*================================util.c===========================*/ + +/* Logging function, returns FAIL to use as a return value in calling funcs */ +int +gerr (int ev, char * fmt, ...) +{ + va_list args; + + va_start (args, fmt); + vprintf(fmt, args); + va_end (args); + + printf("\n"); + + return (FAIL); +} diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h new file mode 100644 index 00000000..b417a56b --- /dev/null +++ b/src/sfloader/fluid_sf2.h @@ -0,0 +1,312 @@ +/* FluidSynth - A Software Synthesizer + * + * Copyright (C) 2003 Peter Hanappe and others. + * + * SoundFont loading code borrowed from Smurf SoundFont Editor by Josh Green + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + + +#ifndef _FLUID_SF2_H +#define _FLUID_SF2_H + + +#include "fluid_gen.h" +#include "fluid_list.h" +#include "fluid_mod.h" +#include "fluidsynth.h" +#include "fluidsynth_priv.h" + + +/* Sound Font structure defines */ + +typedef struct _SFVersion +{ /* version structure */ + unsigned short major; + unsigned short minor; +} +SFVersion; + +typedef struct _SFMod +{ /* Modulator structure */ + unsigned short src; /* source modulator */ + unsigned short dest; /* destination generator */ + signed short amount; /* signed, degree of modulation */ + unsigned short amtsrc; /* second source controls amnt of first */ + unsigned short trans; /* transform applied to source */ +} +SFMod; + +typedef union _SFGenAmount +{ /* Generator amount structure */ + signed short sword; /* signed 16 bit value */ + unsigned short uword; /* unsigned 16 bit value */ + struct + { + unsigned char lo; /* low value for ranges */ + unsigned char hi; /* high value for ranges */ + } + range; +} +SFGenAmount; + +typedef struct _SFGen +{ /* Generator structure */ + unsigned short id; /* generator ID */ + SFGenAmount amount; /* generator value */ +} +SFGen; + +typedef struct _SFZone +{ /* Sample/instrument zone structure */ + fluid_list_t *instsamp; /* instrument/sample pointer for zone */ + fluid_list_t *gen; /* list of generators */ + fluid_list_t *mod; /* list of modulators */ +} +SFZone; + +typedef struct _SFSample +{ /* Sample structure */ + char name[21]; /* Name of sample */ + unsigned char samfile; /* Loaded sfont/sample buffer = 0/1 */ + unsigned int start; /* Offset in sample area to start of sample */ + unsigned int end; /* Offset from start to end of sample, + this is the last point of the + sample, the SF spec has this as the + 1st point after, corrected on + load/save */ + unsigned int loopstart; /* Offset from start to start of loop */ + unsigned int loopend; /* Offset from start to end of loop, + marks the first point after loop, + whose sample value is ideally + equivalent to loopstart */ + unsigned int samplerate; /* Sample rate recorded at */ + unsigned char origpitch; /* root midi key number */ + signed char pitchadj; /* pitch correction in cents */ + unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ + fluid_sample_t *fluid_sample; /* Imported sample (fixed up in fluid_defsfont_load) */ +} +SFSample; + +typedef struct _SFInst +{ /* Instrument structure */ + char name[21]; /* Name of instrument */ + fluid_list_t *zone; /* list of instrument zones */ +} +SFInst; + +typedef struct _SFPreset +{ /* Preset structure */ + char name[21]; /* preset name */ + unsigned short prenum; /* preset number */ + unsigned short bank; /* bank number */ + unsigned int libr; /* Not used (preserved) */ + unsigned int genre; /* Not used (preserved) */ + unsigned int morph; /* Not used (preserved) */ + fluid_list_t *zone; /* list of preset zones */ +} +SFPreset; + +/* NOTE: sffd is also used to determine if sound font is new (NULL) */ +typedef struct _SFData +{ /* Sound font data structure */ + SFVersion version; /* sound font version */ + SFVersion romver; /* ROM version */ + + unsigned int samplepos; /* position within sffd of the sample chunk */ + unsigned int samplesize; /* length within sffd of the sample chunk */ + + unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */ + unsigned int sample24size; /* length within sffd of the sm24 chunk */ + + char *fname; /* file name */ + FILE *sffd; /* loaded sfont file descriptor */ + 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 */ + fluid_list_t *sample; /* linked list of sample info */ +} +SFData; + +/* sf file chunk IDs */ +enum +{ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, + INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */ + + IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */ + IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */ + ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */ + + SNAM_ID, SMPL_ID, /* sample ids */ + PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ + IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ + SHDR_ID, /* sample info */ + SM24_ID +}; + +/* generator types */ +typedef enum +{ Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch, + Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ, + Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs, + Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan, + Gen_Unused2, Gen_Unused3, Gen_Unused4, + Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq, + Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay, + Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold, + Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack, + Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease, + Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument, + Gen_Reserved1, Gen_KeyRange, Gen_VelRange, + Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, + Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs, + Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes, + Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey, + Gen_Dummy +} +Gen_Type; + +#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ +#define Gen_Count Gen_Dummy /* count of generators */ +#define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ + +/* generator unit type */ +typedef enum +{ + None, /* No unit type */ + Unit_Smpls, /* in samples */ + Unit_32kSmpls, /* in 32k samples */ + Unit_Cent, /* in cents (1/100th of a semitone) */ + Unit_HzCent, /* in Hz Cents */ + Unit_TCent, /* in Time Cents */ + Unit_cB, /* in centibels (1/100th of a decibel) */ + Unit_Percent, /* in percentage */ + Unit_Semitone, /* in semitones */ + Unit_Range /* a range of values */ +} +Gen_Unit; + +/* functions */ +void sfont_init_chunks (void); + +void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs); +void sfont_free_zone (SFZone * zone); +int sfont_preset_compare_func (void* a, void* b); + +void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone); + +fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist); +int gen_valid (int gen); +int gen_validp (int gen); + + +/*-----------------------------------sffile.h----------------------------*/ +/* + File structures and routines (used to be in sffile.h) +*/ + +#define CHNKIDSTR(id) &idlist[(id - 1) * 4] + +/* sfont file chunk sizes */ +#define SFPHDRSIZE 38 +#define SFBAGSIZE 4 +#define SFMODSIZE 10 +#define SFGENSIZE 4 +#define SFIHDRSIZE 22 +#define SFSHDRSIZE 46 + +/* sfont file data structures */ +typedef struct _SFChunk +{ /* RIFF file chunk structure */ + unsigned int id; /* chunk id */ + unsigned int size; /* size of the following chunk */ +} +SFChunk; + +typedef struct _SFPhdr +{ + unsigned char name[20]; /* preset name */ + unsigned short preset; /* preset number */ + unsigned short bank; /* bank number */ + unsigned short pbagndx; /* index into preset bag */ + unsigned int library; /* just for preserving them */ + unsigned int genre; /* Not used */ + unsigned int morphology; /* Not used */ +} +SFPhdr; + +typedef struct _SFBag +{ + unsigned short genndx; /* index into generator list */ + unsigned short modndx; /* index into modulator list */ +} +SFBag; + +typedef struct _SFIhdr +{ + char name[20]; /* Name of instrument */ + unsigned short ibagndx; /* Instrument bag index */ +} +SFIhdr; + +typedef struct _SFShdr +{ /* Sample header loading struct */ + char name[20]; /* Sample name */ + unsigned int start; /* Offset to start of sample */ + unsigned int end; /* Offset to end of sample */ + unsigned int loopstart; /* Offset to start of loop */ + unsigned int loopend; /* Offset to end of loop */ + unsigned int samplerate; /* Sample rate recorded at */ + unsigned char origpitch; /* root midi key number */ + signed char pitchadj; /* pitch correction in cents */ + unsigned short samplelink; /* Not used */ + unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ +} +SFShdr; + +/* functions */ +SFData *sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs); + + + +/********************************************************************************/ +/********************************************************************************/ +/********************************************************************************/ +/********************************************************************************/ +/********************************************************************************/ + + +/*-----------------------------------util.h----------------------------*/ +/* + Utility functions (formerly in util.h) + */ +#define FAIL 0 +#define OK 1 + +enum +{ ErrWarn, ErrFatal, ErrStatus, ErrCorr, ErrEof, ErrMem, Errno, + ErrRead, ErrWrite +}; + +#define ErrMax ErrWrite +#define ErrnoStart Errno +#define ErrnoEnd ErrWrite + +int gerr (int ev, char * fmt, ...); + +#endif /* _FLUID_SF2_H */ From 167048f5a355830e7e77f171ccfb44026ac805f1 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 02/47] Remove reference to defsfont from low-level function --- src/sfloader/fluid_sf2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 82bc2f42..87ccf640 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -1350,7 +1350,7 @@ fixup_sample (SFData * sf) int invalid_loopstart; int invalid_loopend, loopend_end_mismatch; unsigned int total_bytes = sf->samplesize; - unsigned int total_samples = total_bytes / FLUID_MEMBER_SIZE(fluid_defsfont_t, sampledata[0]); + unsigned int total_samples = total_bytes / sizeof(short); p = sf->sample; while (p) From 12902f7454288e5489cf0294218ebd6acfaa48b1 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 03/47] Remove unused defines and declarations --- src/sfloader/fluid_sf2.c | 9 --------- src/sfloader/fluid_sf2.h | 26 ++------------------------ 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 87ccf640..30551277 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -1453,15 +1453,6 @@ next_sample: Smurf SoundFont Editor ================================================================*/ - -/* optimum chunk area sizes (could be more optimum) */ -#define PRESET_CHUNK_OPTIMUM_AREA 256 -#define INST_CHUNK_OPTIMUM_AREA 256 -#define SAMPLE_CHUNK_OPTIMUM_AREA 256 -#define ZONE_CHUNK_OPTIMUM_AREA 256 -#define MOD_CHUNK_OPTIMUM_AREA 256 -#define GEN_CHUNK_OPTIMUM_AREA 256 - static const unsigned short badgen[] = { Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h index b417a56b..663bb7a7 100644 --- a/src/sfloader/fluid_sf2.h +++ b/src/sfloader/fluid_sf2.h @@ -185,25 +185,7 @@ Gen_Type; #define Gen_Count Gen_Dummy /* count of generators */ #define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ -/* generator unit type */ -typedef enum -{ - None, /* No unit type */ - Unit_Smpls, /* in samples */ - Unit_32kSmpls, /* in 32k samples */ - Unit_Cent, /* in cents (1/100th of a semitone) */ - Unit_HzCent, /* in Hz Cents */ - Unit_TCent, /* in Time Cents */ - Unit_cB, /* in centibels (1/100th of a decibel) */ - Unit_Percent, /* in percentage */ - Unit_Semitone, /* in semitones */ - Unit_Range /* a range of values */ -} -Gen_Unit; - /* functions */ -void sfont_init_chunks (void); - void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs); void sfont_free_zone (SFZone * zone); int sfont_preset_compare_func (void* a, void* b); @@ -299,14 +281,10 @@ SFData *sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs); #define OK 1 enum -{ ErrWarn, ErrFatal, ErrStatus, ErrCorr, ErrEof, ErrMem, Errno, - ErrRead, ErrWrite +{ + ErrCorr, }; -#define ErrMax ErrWrite -#define ErrnoStart Errno -#define ErrnoEnd ErrWrite - int gerr (int ev, char * fmt, ...); #endif /* _FLUID_SF2_H */ From 5c58c304b9aca240f9892af37524f96da2b20a22 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 04/47] Move declarations to top of file --- src/sfloader/fluid_sf2.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 30551277..7cb4b375 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -36,6 +36,19 @@ equivalent to the matching ID list in memory regardless of LE/BE machine */ +static const unsigned short badgen[] = { + Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, + Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 +}; + +static const unsigned short badpgen[] = { + Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs, + Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, + Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass, + Gen_OverrideRootKey, 0 +}; + #define READCHUNK(var,fd, fcbs) do { \ if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ return(FAIL); \ @@ -1449,23 +1462,6 @@ next_sample: return (OK); } -/*=================================sfont.c======================== - Smurf SoundFont Editor - ================================================================*/ - -static const unsigned short badgen[] = { - Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 -}; - -static const unsigned short badpgen[] = { - Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass, - Gen_OverrideRootKey, 0 -}; - /* close SoundFont file and delete a SoundFont structure */ void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs) From 333e8a1295c236b4e02374b0ac94fda2a6b5a731 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 05/47] Move private defines from fluid_sf2.h to fluid_sf2.c --- src/sfloader/fluid_sf2.c | 77 +++++++++++++++++++++++++++++++++++ src/sfloader/fluid_sf2.h | 86 +--------------------------------------- 2 files changed, 79 insertions(+), 84 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 7cb4b375..889adb01 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -36,6 +36,50 @@ equivalent to the matching ID list in memory regardless of LE/BE machine */ +/* sf file chunk IDs */ +enum +{ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, + INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */ + + IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */ + IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */ + ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */ + + SNAM_ID, SMPL_ID, /* sample ids */ + PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ + IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ + SHDR_ID, /* sample info */ + SM24_ID +}; + +/* generator types */ +typedef enum +{ Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch, + Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ, + Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs, + Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan, + Gen_Unused2, Gen_Unused3, Gen_Unused4, + Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq, + Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay, + Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold, + Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack, + Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease, + Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument, + Gen_Reserved1, Gen_KeyRange, Gen_VelRange, + Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, + Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs, + Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes, + Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey, + Gen_Dummy +} +Gen_Type; + +#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ +#define Gen_Count Gen_Dummy /* count of generators */ +#define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ + + static const unsigned short badgen[] = { Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 @@ -49,6 +93,29 @@ static const unsigned short badpgen[] = { Gen_OverrideRootKey, 0 }; + +#define FAIL 0 +#define OK 1 + +enum +{ + ErrCorr, +}; + +int gerr (int ev, char * fmt, ...); + + +#define CHNKIDSTR(id) &idlist[(id - 1) * 4] + +/* sfont file chunk sizes */ +#define SFPHDRSIZE 38 +#define SFBAGSIZE 4 +#define SFMODSIZE 10 +#define SFGENSIZE 4 +#define SFIHDRSIZE 22 +#define SFSHDRSIZE 46 + + #define READCHUNK(var,fd, fcbs) do { \ if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ return(FAIL); \ @@ -124,6 +191,16 @@ static int fixup_pgen (SFData * sf); static int fixup_igen (SFData * sf); static int fixup_sample (SFData * sf); + +void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone); +int sfont_preset_compare_func (void* a, void* b); +void sfont_free_zone (SFZone * zone); +fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist); +int gen_valid (int gen); +int gen_validp (int gen); + + + static const char idlist[] = { "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24" diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h index 663bb7a7..acee033e 100644 --- a/src/sfloader/fluid_sf2.h +++ b/src/sfloader/fluid_sf2.h @@ -142,59 +142,9 @@ typedef struct _SFData } SFData; -/* sf file chunk IDs */ -enum -{ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, - INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */ - - IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */ - IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */ - ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */ - - SNAM_ID, SMPL_ID, /* sample ids */ - PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ - IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ - SHDR_ID, /* sample info */ - SM24_ID -}; - -/* generator types */ -typedef enum -{ Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch, - Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ, - Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs, - Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan, - Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq, - Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay, - Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold, - Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack, - Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease, - Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument, - Gen_Reserved1, Gen_KeyRange, Gen_VelRange, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs, - Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes, - Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey, - Gen_Dummy -} -Gen_Type; - -#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ -#define Gen_Count Gen_Dummy /* count of generators */ -#define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ - /* functions */ -void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs); -void sfont_free_zone (SFZone * zone); -int sfont_preset_compare_func (void* a, void* b); -void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone); -fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist); -int gen_valid (int gen); -int gen_validp (int gen); /*-----------------------------------sffile.h----------------------------*/ @@ -202,16 +152,6 @@ int gen_validp (int gen); File structures and routines (used to be in sffile.h) */ -#define CHNKIDSTR(id) &idlist[(id - 1) * 4] - -/* sfont file chunk sizes */ -#define SFPHDRSIZE 38 -#define SFBAGSIZE 4 -#define SFMODSIZE 10 -#define SFGENSIZE 4 -#define SFIHDRSIZE 22 -#define SFSHDRSIZE 46 - /* sfont file data structures */ typedef struct _SFChunk { /* RIFF file chunk structure */ @@ -261,30 +201,8 @@ typedef struct _SFShdr } SFShdr; -/* functions */ +/* Public functions */ SFData *sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs); - - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - -/*-----------------------------------util.h----------------------------*/ -/* - Utility functions (formerly in util.h) - */ -#define FAIL 0 -#define OK 1 - -enum -{ - ErrCorr, -}; - -int gerr (int ev, char * fmt, ...); +void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs); #endif /* _FLUID_SF2_H */ From 79c3bebaeaaab07185d64fbc46110ae5160c9f25 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 06/47] Source formatting (clang-format) --- src/sfloader/fluid_sf2.c | 2721 +++++++++++++++++++------------------- src/sfloader/fluid_sf2.h | 243 ++-- 2 files changed, 1492 insertions(+), 1472 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 889adb01..26b422f8 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -22,9 +22,9 @@ */ -#include "fluid_sys.h" -#include "fluid_sfont.h" #include "fluid_sf2.h" +#include "fluid_sfont.h" +#include "fluid_sys.h" /*=================================sfload.c======================== Borrowed from Smurf SoundFont Editor by Josh Green @@ -38,762 +38,825 @@ /* sf file chunk IDs */ enum -{ UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID, - INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */ +{ + UNKN_ID, + RIFF_ID, + LIST_ID, + SFBK_ID, + INFO_ID, + SDTA_ID, + PDTA_ID, /* info/sample/preset */ - IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */ - IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */ - ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */ + IFIL_ID, + ISNG_ID, + INAM_ID, + IROM_ID, /* info ids (1st byte of info strings) */ + IVER_ID, + ICRD_ID, + IENG_ID, + IPRD_ID, /* more info ids */ + ICOP_ID, + ICMT_ID, + ISFT_ID, /* and yet more info ids */ - SNAM_ID, SMPL_ID, /* sample ids */ - PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */ - IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */ - SHDR_ID, /* sample info */ - SM24_ID + SNAM_ID, + SMPL_ID, /* sample ids */ + PHDR_ID, + PBAG_ID, + PMOD_ID, + PGEN_ID, /* preset ids */ + IHDR_ID, + IBAG_ID, + IMOD_ID, + IGEN_ID, /* instrument ids */ + SHDR_ID, /* sample info */ + SM24_ID }; /* generator types */ -typedef enum -{ Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch, - Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ, - Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs, - Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan, - Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq, - Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay, - Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold, - Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack, - Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease, - Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument, - Gen_Reserved1, Gen_KeyRange, Gen_VelRange, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs, - Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes, - Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey, - Gen_Dummy -} -Gen_Type; +typedef enum { + Gen_StartAddrOfs, + Gen_EndAddrOfs, + Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, + Gen_StartAddrCoarseOfs, + Gen_ModLFO2Pitch, + Gen_VibLFO2Pitch, + Gen_ModEnv2Pitch, + Gen_FilterFc, + Gen_FilterQ, + Gen_ModLFO2FilterFc, + Gen_ModEnv2FilterFc, + Gen_EndAddrCoarseOfs, + Gen_ModLFO2Vol, + Gen_Unused1, + Gen_ChorusSend, + Gen_ReverbSend, + Gen_Pan, + Gen_Unused2, + Gen_Unused3, + Gen_Unused4, + Gen_ModLFODelay, + Gen_ModLFOFreq, + Gen_VibLFODelay, + Gen_VibLFOFreq, + Gen_ModEnvDelay, + Gen_ModEnvAttack, + Gen_ModEnvHold, + Gen_ModEnvDecay, + Gen_ModEnvSustain, + Gen_ModEnvRelease, + Gen_Key2ModEnvHold, + Gen_Key2ModEnvDecay, + Gen_VolEnvDelay, + Gen_VolEnvAttack, + Gen_VolEnvHold, + Gen_VolEnvDecay, + Gen_VolEnvSustain, + Gen_VolEnvRelease, + Gen_Key2VolEnvHold, + Gen_Key2VolEnvDecay, + Gen_Instrument, + Gen_Reserved1, + Gen_KeyRange, + Gen_VelRange, + Gen_StartLoopAddrCoarseOfs, + Gen_Keynum, + Gen_Velocity, + Gen_Attenuation, + Gen_Reserved2, + Gen_EndLoopAddrCoarseOfs, + Gen_CoarseTune, + Gen_FineTune, + Gen_SampleId, + Gen_SampleModes, + Gen_Reserved3, + Gen_ScaleTune, + Gen_ExclusiveClass, + Gen_OverrideRootKey, + Gen_Dummy +} Gen_Type; -#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ -#define Gen_Count Gen_Dummy /* count of generators */ -#define GenArrSize sizeof(SFGenAmount)*Gen_Count /* gen array size */ +#define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */ +#define Gen_Count Gen_Dummy /* count of generators */ +#define GenArrSize sizeof(SFGenAmount) * Gen_Count /* gen array size */ -static const unsigned short badgen[] = { - Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0 -}; +static const unsigned short badgen[] = {Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, + Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0}; -static const unsigned short badpgen[] = { - Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs, - Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity, - Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass, - Gen_OverrideRootKey, 0 -}; +static const unsigned short badpgen[] = {Gen_StartAddrOfs, + Gen_EndAddrOfs, + Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, + Gen_StartAddrCoarseOfs, + Gen_EndAddrCoarseOfs, + Gen_StartLoopAddrCoarseOfs, + Gen_Keynum, + Gen_Velocity, + Gen_EndLoopAddrCoarseOfs, + Gen_SampleModes, + Gen_ExclusiveClass, + Gen_OverrideRootKey, + 0}; -#define FAIL 0 -#define OK 1 +#define FAIL 0 +#define OK 1 enum { ErrCorr, }; -int gerr (int ev, char * fmt, ...); +int gerr(int ev, char *fmt, ...); -#define CHNKIDSTR(id) &idlist[(id - 1) * 4] +#define CHNKIDSTR(id) &idlist[(id - 1) * 4] /* sfont file chunk sizes */ -#define SFPHDRSIZE 38 -#define SFBAGSIZE 4 -#define SFMODSIZE 10 -#define SFGENSIZE 4 -#define SFIHDRSIZE 22 -#define SFSHDRSIZE 46 +#define SFPHDRSIZE 38 +#define SFBAGSIZE 4 +#define SFMODSIZE 10 +#define SFGENSIZE 4 +#define SFIHDRSIZE 22 +#define SFSHDRSIZE 46 -#define READCHUNK(var,fd, fcbs) do { \ - if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ - return(FAIL); \ - ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \ -} while(0) +#define READCHUNK(var, fd, fcbs) \ + do \ + { \ + if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ + return (FAIL); \ + ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \ + } while (0) -#define READD(var,fd, fcbs) do { \ - uint32_t _temp; \ - if (fcbs->fread(&_temp, 4, fd) == FLUID_FAILED) \ - return(FAIL); \ - var = FLUID_LE32TOH(_temp); \ -} while(0) +#define READD(var, fd, fcbs) \ + do \ + { \ + uint32_t _temp; \ + if (fcbs->fread(&_temp, 4, fd) == FLUID_FAILED) \ + return (FAIL); \ + var = FLUID_LE32TOH(_temp); \ + } while (0) -#define READW(var,fd, fcbs) do { \ - uint16_t _temp; \ - if (fcbs->fread(&_temp, 2, fd) == FLUID_FAILED) \ - return(FAIL); \ - var = FLUID_LE16TOH(_temp); \ -} while(0) +#define READW(var, fd, fcbs) \ + do \ + { \ + uint16_t _temp; \ + if (fcbs->fread(&_temp, 2, fd) == FLUID_FAILED) \ + return (FAIL); \ + var = FLUID_LE16TOH(_temp); \ + } while (0) -#define READID(var,fd, fcbs) do { \ - if (fcbs->fread(var, 4, fd) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) +#define READID(var, fd, fcbs) \ + do \ + { \ + if (fcbs->fread(var, 4, fd) == FLUID_FAILED) \ + return (FAIL); \ + } while (0) -#define READSTR(var,fd, fcbs) do { \ - if (fcbs->fread(var, 20, fd) == FLUID_FAILED) \ - return(FAIL); \ - (*var)[20] = '\0'; \ -} while(0) +#define READSTR(var, fd, fcbs) \ + do \ + { \ + if (fcbs->fread(var, 20, fd) == FLUID_FAILED) \ + return (FAIL); \ + (*var)[20] = '\0'; \ + } while (0) -#define READB(var,fd, fcbs) do { \ - if (fcbs->fread(&var, 1, fd) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) +#define READB(var, fd, fcbs) \ + do \ + { \ + if (fcbs->fread(&var, 1, fd) == FLUID_FAILED) \ + return (FAIL); \ + } while (0) -#define FSKIP(size,fd, fcbs) do { \ - if (fcbs->fseek(fd, size, SEEK_CUR) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) +#define FSKIP(size, fd, fcbs) \ + do \ + { \ + if (fcbs->fseek(fd, size, SEEK_CUR) == FLUID_FAILED) \ + return (FAIL); \ + } while (0) -#define FSKIPW(fd, fcbs) do { \ - if (fcbs->fseek(fd, 2, SEEK_CUR) == FLUID_FAILED) \ - return(FAIL); \ -} while(0) +#define FSKIPW(fd, fcbs) \ + do \ + { \ + if (fcbs->fseek(fd, 2, SEEK_CUR) == FLUID_FAILED) \ + return (FAIL); \ + } while (0) /* removes and advances a fluid_list_t pointer */ -#define SLADVREM(list, item) do { \ - fluid_list_t *_temp = item; \ - item = fluid_list_next(item); \ - list = fluid_list_remove_link(list, _temp); \ - delete1_fluid_list(_temp); \ -} while(0) +#define SLADVREM(list, item) \ + do \ + { \ + fluid_list_t *_temp = item; \ + item = fluid_list_next(item); \ + list = fluid_list_remove_link(list, _temp); \ + delete1_fluid_list(_temp); \ + } while (0) -static int chunkid (unsigned int id); -static int load_body (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int read_listchunk (SFChunk * chunk, void * fd, const fluid_file_callbacks_t* fcbs); -static int process_info (int size, SFData * sf, void* fd, const fluid_file_callbacks_t* fcbs); -static int process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, - int * size, void * fd, const fluid_file_callbacks_t* fcbs); -static int process_pdta (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_phdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_pbag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_pgen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_ihdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_ibag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_imod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_igen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int load_shdr (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs); -static int fixup_pgen (SFData * sf); -static int fixup_igen (SFData * sf); -static int fixup_sample (SFData * sf); +static int chunkid(unsigned int id); +static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t *fcbs); +static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int +pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size, void *fd, const fluid_file_callbacks_t *fcbs); +static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int fixup_pgen(SFData *sf); +static int fixup_igen(SFData *sf); +static int fixup_sample(SFData *sf); -void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone); -int sfont_preset_compare_func (void* a, void* b); -void sfont_free_zone (SFZone * zone); -fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist); -int gen_valid (int gen); -int gen_validp (int gen); +void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone); +int sfont_preset_compare_func(void *a, void *b); +void sfont_free_zone(SFZone *zone); +fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist); +int gen_valid(int gen); +int gen_validp(int gen); - -static const char idlist[] = { - "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" - "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24" -}; +static const char idlist[] = {"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" + "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24"}; /* sound font file load functions */ -static int -chunkid (unsigned int id) +static int chunkid(unsigned int id) { - unsigned int i; - unsigned int *p; + unsigned int i; + unsigned int *p; - p = (unsigned int *) & idlist; - for (i = 0; i < sizeof (idlist) / sizeof (int); i++, p += 1) - if (*p == id) - return (i + 1); + p = (unsigned int *)&idlist; + for (i = 0; i < sizeof(idlist) / sizeof(int); i++, p += 1) + if (*p == id) + return (i + 1); - return (UNKN_ID); + return (UNKN_ID); } -SFData * -sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs) +SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs) { - SFData *sf = NULL; - void *fd; - int fsize = 0; - int err = FALSE; + SFData *sf = NULL; + void *fd; + int fsize = 0; + int err = FALSE; - if ((fd = fcbs->fopen (fname)) == NULL) + if ((fd = fcbs->fopen(fname)) == NULL) { - FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname); - return (NULL); + FLUID_LOG(FLUID_ERR, _("Unable to open file \"%s\""), fname); + return (NULL); } - if (!(sf = FLUID_NEW (SFData))) + if (!(sf = FLUID_NEW(SFData))) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - fclose(fd); - err = TRUE; + FLUID_LOG(FLUID_ERR, "Out of memory"); + fclose(fd); + err = TRUE; } - if (!err) + if (!err) { - memset (sf, 0, sizeof (SFData)); /* zero sfdata */ - sf->fname = FLUID_STRDUP (fname); /* copy file name */ - sf->sffd = fd; + memset(sf, 0, sizeof(SFData)); /* zero sfdata */ + sf->fname = FLUID_STRDUP(fname); /* copy file name */ + sf->sffd = fd; } - /* get size of file */ - if (!err && fcbs->fseek (fd, 0L, SEEK_END) == FLUID_FAILED) - { /* seek to end of file */ - err = TRUE; - FLUID_LOG (FLUID_ERR, _("Seek to end of file failed")); + /* get size of file */ + if (!err && fcbs->fseek(fd, 0L, SEEK_END) == FLUID_FAILED) + { /* seek to end of file */ + err = TRUE; + FLUID_LOG(FLUID_ERR, _("Seek to end of file failed")); } - if (!err && (fsize = fcbs->ftell (fd)) == FLUID_FAILED) - { /* position = size */ - err = TRUE; - FLUID_LOG (FLUID_ERR, _("Get end of file position failed")); + if (!err && (fsize = fcbs->ftell(fd)) == FLUID_FAILED) + { /* position = size */ + err = TRUE; + FLUID_LOG(FLUID_ERR, _("Get end of file position failed")); } - if (!err) - rewind (fd); + if (!err) + rewind(fd); - if (!err && !load_body (fsize, sf, fd, fcbs)) - err = TRUE; /* load the sfont */ + if (!err && !load_body(fsize, sf, fd, fcbs)) + err = TRUE; /* load the sfont */ - if (err) + if (err) { - if (sf) - sfont_close (sf, fcbs); - return (NULL); + if (sf) + sfont_close(sf, fcbs); + return (NULL); } - return (sf); + return (sf); } -static int -load_body (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - SFChunk chunk; + SFChunk chunk; - READCHUNK (&chunk, fd, fcbs); /* load RIFF chunk */ - if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */ - FLUID_LOG (FLUID_ERR, _("Not a RIFF file")); - return (FAIL); - } - - READID (&chunk.id, fd, fcbs); /* load file ID */ - if (chunkid (chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ - FLUID_LOG (FLUID_ERR, _("Not a SoundFont file")); - return (FAIL); - } - - if (chunk.size != size - 8) { - gerr (ErrCorr, _("SoundFont file size mismatch")); - return (FAIL); - } - - /* Process INFO block */ - if (!read_listchunk (&chunk, fd, fcbs)) - return (FAIL); - if (chunkid (chunk.id) != INFO_ID) - return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk"))); - if (!process_info (chunk.size, sf, fd, fcbs)) - return (FAIL); - - /* Process sample chunk */ - if (!read_listchunk (&chunk, fd, fcbs)) - return (FAIL); - if (chunkid (chunk.id) != SDTA_ID) - return (gerr (ErrCorr, - _("Invalid ID found when expecting SAMPLE chunk"))); - if (!process_sdta (chunk.size, sf, fd, fcbs)) - return (FAIL); - - /* process HYDRA chunk */ - if (!read_listchunk (&chunk, fd, fcbs)) - return (FAIL); - if (chunkid (chunk.id) != PDTA_ID) - return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk"))); - if (!process_pdta (chunk.size, sf, fd, fcbs)) - return (FAIL); - - if (!fixup_pgen (sf)) - return (FAIL); - if (!fixup_igen (sf)) - return (FAIL); - if (!fixup_sample (sf)) - return (FAIL); - - /* sort preset list by bank, preset # */ - sf->preset = fluid_list_sort (sf->preset, - (fluid_compare_func_t) sfont_preset_compare_func); - - return (OK); -} - -static int -read_listchunk (SFChunk * chunk, void * fd, const fluid_file_callbacks_t* fcbs) -{ - READCHUNK (chunk, fd, fcbs); /* read list chunk */ - if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */ - return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse"))); - READID (&chunk->id, fd, fcbs); /* read id string */ - chunk->size -= 4; - return (OK); -} - -static int -process_info (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) -{ - SFChunk chunk; - unsigned char id; - char *item; - unsigned short ver; - - while (size > 0) - { - READCHUNK (&chunk, fd, fcbs); - size -= 8; - - id = chunkid (chunk.id); - - if (id == IFIL_ID) - { /* sound font version chunk? */ - if (chunk.size != 4) - return (gerr (ErrCorr, - _("Sound font version info chunk has invalid size"))); - - READW (ver, fd, fcbs); - sf->version.major = ver; - READW (ver, fd, fcbs); - sf->version.minor = ver; - - if (sf->version.major < 2) { - FLUID_LOG (FLUID_ERR, - _("Sound font version is %d.%d which is not" - " supported, convert to version 2.0x"), - sf->version.major, - sf->version.minor); - return (FAIL); - } - - if (sf->version.major == 3) { -#if !LIBSNDFILE_SUPPORT - FLUID_LOG (FLUID_WARN, - _("Sound font version is %d.%d but fluidsynth was compiled without" - " support for (v3.x)"), - sf->version.major, - sf->version.minor); - return (FAIL); -#endif - } - else if (sf->version.major > 2) { - FLUID_LOG (FLUID_WARN, - _("Sound font version is %d.%d which is newer than" - " what this version of fluidsynth was designed for (v2.0x)"), - sf->version.major, - sf->version.minor); - return (FAIL); - } - } - else if (id == IVER_ID) - { /* ROM version chunk? */ - if (chunk.size != 4) - return (gerr (ErrCorr, - _("ROM version info chunk has invalid size"))); - - READW (ver, fd, fcbs); - sf->romver.major = ver; - READW (ver, fd, fcbs); - sf->romver.minor = ver; - } - else if (id != UNKN_ID) - { - if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) - || (chunk.size % 2)) - return (gerr (ErrCorr, - _("INFO sub chunk %.4s has invalid chunk size" - " of %d bytes"), &chunk.id, chunk.size)); - - /* alloc for chunk id and da chunk */ - 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); - - *(unsigned char *) item = id; - if (fcbs->fread(&item[1], chunk.size, fd) == FLUID_FAILED) - return (FAIL); - - /* force terminate info item (don't forget uint8 info ID) */ - *(item + chunk.size) = '\0'; - } - else - return (gerr (ErrCorr, _("Invalid chunk id in INFO chunk"))); - size -= chunk.size; + READCHUNK(&chunk, fd, fcbs); /* load RIFF chunk */ + if (chunkid(chunk.id) != RIFF_ID) + { /* error if not RIFF */ + FLUID_LOG(FLUID_ERR, _("Not a RIFF file")); + return (FAIL); } - if (size < 0) - return (gerr (ErrCorr, _("INFO chunk size mismatch"))); + READID(&chunk.id, fd, fcbs); /* load file ID */ + if (chunkid(chunk.id) != SFBK_ID) + { /* error if not SFBK_ID */ + FLUID_LOG(FLUID_ERR, _("Not a SoundFont file")); + return (FAIL); + } - return (OK); + if (chunk.size != size - 8) + { + gerr(ErrCorr, _("SoundFont file size mismatch")); + return (FAIL); + } + + /* Process INFO block */ + if (!read_listchunk(&chunk, fd, fcbs)) + return (FAIL); + if (chunkid(chunk.id) != INFO_ID) + return (gerr(ErrCorr, _("Invalid ID found when expecting INFO chunk"))); + if (!process_info(chunk.size, sf, fd, fcbs)) + return (FAIL); + + /* Process sample chunk */ + if (!read_listchunk(&chunk, fd, fcbs)) + return (FAIL); + if (chunkid(chunk.id) != SDTA_ID) + return (gerr(ErrCorr, _("Invalid ID found when expecting SAMPLE chunk"))); + if (!process_sdta(chunk.size, sf, fd, fcbs)) + return (FAIL); + + /* process HYDRA chunk */ + if (!read_listchunk(&chunk, fd, fcbs)) + return (FAIL); + if (chunkid(chunk.id) != PDTA_ID) + return (gerr(ErrCorr, _("Invalid ID found when expecting HYDRA chunk"))); + if (!process_pdta(chunk.size, sf, fd, fcbs)) + return (FAIL); + + if (!fixup_pgen(sf)) + return (FAIL); + if (!fixup_igen(sf)) + return (FAIL); + if (!fixup_sample(sf)) + return (FAIL); + + /* sort preset list by bank, preset # */ + sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)sfont_preset_compare_func); + + return (OK); } -static int -process_sdta (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t *fcbs) { - SFChunk chunk; + READCHUNK(chunk, fd, fcbs); /* read list chunk */ + if (chunkid(chunk->id) != LIST_ID) /* error if ! list chunk */ + return (gerr(ErrCorr, _("Invalid chunk id in level 0 parse"))); + READID(&chunk->id, fd, fcbs); /* read id string */ + chunk->size -= 4; + return (OK); +} - if (size == 0) - return (OK); /* no sample data? */ +static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +{ + SFChunk chunk; + unsigned char id; + char *item; + unsigned short ver; - /* read sub chunk */ - READCHUNK (&chunk, fd, fcbs); - size -= 8; - - if (chunkid (chunk.id) != SMPL_ID) - return (gerr (ErrCorr, - _("Expected SMPL chunk found invalid id instead"))); - - /* SDTA chunk may also contain sm24 chunk for 24 bit samples - * (not yet supported), only an error if SMPL chunk size is - * greater than SDTA. */ - if (chunk.size > size) - return (gerr (ErrCorr, _("SDTA chunk size mismatch"))); - - /* sample data follows */ - sf->samplepos = fcbs->ftell (fd); - - /* used in fixup_sample() to check validity of sample headers */ - sf->samplesize = chunk.size; - - FSKIP (chunk.size, fd, fcbs); - size -= chunk.size; - - if(sf->version.major >= 2 && sf->version.minor >= 4) - { - /* any chance to find another chunk here? */ - if(size > 8) + while (size > 0) { - /* read sub chunk */ - READCHUNK (&chunk, fd, fcbs); + READCHUNK(&chunk, fd, fcbs); size -= 8; - - if (chunkid (chunk.id) == SM24_ID) + + id = chunkid(chunk.id); + + if (id == IFIL_ID) + { /* sound font version chunk? */ + if (chunk.size != 4) + return (gerr(ErrCorr, _("Sound font version info chunk has invalid size"))); + + READW(ver, fd, fcbs); + sf->version.major = ver; + READW(ver, fd, fcbs); + sf->version.minor = ver; + + if (sf->version.major < 2) + { + FLUID_LOG(FLUID_ERR, _("Sound font version is %d.%d which is not" + " supported, convert to version 2.0x"), + sf->version.major, sf->version.minor); + return (FAIL); + } + + if (sf->version.major == 3) + { +#if !LIBSNDFILE_SUPPORT + FLUID_LOG(FLUID_WARN, + _("Sound font version is %d.%d but fluidsynth was compiled without" + " support for (v3.x)"), + sf->version.major, sf->version.minor); + return (FAIL); +#endif + } + else if (sf->version.major > 2) + { + FLUID_LOG(FLUID_WARN, + _("Sound font version is %d.%d which is newer than" + " what this version of fluidsynth was designed for (v2.0x)"), + sf->version.major, sf->version.minor); + return (FAIL); + } + } + else if (id == IVER_ID) + { /* ROM version chunk? */ + if (chunk.size != 4) + return (gerr(ErrCorr, _("ROM version info chunk has invalid size"))); + + READW(ver, fd, fcbs); + sf->romver.major = ver; + READW(ver, fd, fcbs); + sf->romver.minor = ver; + } + else if (id != UNKN_ID) { - int sm24size, sdtahalfsize; - - FLUID_LOG(FLUID_DBG, "Found SM24 chunk"); - if (chunk.size > size) + if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) || (chunk.size % 2)) + return (gerr(ErrCorr, _("INFO sub chunk %.4s has invalid chunk size" + " of %d bytes"), + &chunk.id, chunk.size)); + + /* alloc for chunk id and da chunk */ + if (!(item = FLUID_MALLOC(chunk.size + 1))) { - FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24"); - goto ret; // no error + FLUID_LOG(FLUID_ERR, "Out of memory"); + return (FAIL); } - - sdtahalfsize = sf->samplesize/2; - /* + 1 byte in the case that half the size of smpl chunk is an odd value */ - sdtahalfsize += sdtahalfsize%2; - sm24size = chunk.size; - - if (sdtahalfsize != sm24size) + + /* attach to INFO list, sfont_close will cleanup if FAIL occurs */ + sf->info = fluid_list_append(sf->info, item); + + *(unsigned char *)item = id; + if (fcbs->fread(&item[1], chunk.size, fd) == FLUID_FAILED) + return (FAIL); + + /* force terminate info item (don't forget uint8 info ID) */ + *(item + chunk.size) = '\0'; + } + else + return (gerr(ErrCorr, _("Invalid chunk id in INFO chunk"))); + size -= chunk.size; + } + + if (size < 0) + return (gerr(ErrCorr, _("INFO chunk size mismatch"))); + + return (OK); +} + +static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +{ + SFChunk chunk; + + if (size == 0) + return (OK); /* no sample data? */ + + /* read sub chunk */ + READCHUNK(&chunk, fd, fcbs); + size -= 8; + + if (chunkid(chunk.id) != SMPL_ID) + return (gerr(ErrCorr, _("Expected SMPL chunk found invalid id instead"))); + + /* SDTA chunk may also contain sm24 chunk for 24 bit samples + * (not yet supported), only an error if SMPL chunk size is + * greater than SDTA. */ + if (chunk.size > size) + return (gerr(ErrCorr, _("SDTA chunk size mismatch"))); + + /* sample data follows */ + sf->samplepos = fcbs->ftell(fd); + + /* used in fixup_sample() to check validity of sample headers */ + sf->samplesize = chunk.size; + + FSKIP(chunk.size, fd, fcbs); + size -= chunk.size; + + if (sf->version.major >= 2 && sf->version.minor >= 4) + { + /* any chance to find another chunk here? */ + if (size > 8) + { + /* read sub chunk */ + READCHUNK(&chunk, fd, fcbs); + size -= 8; + + if (chunkid(chunk.id) == SM24_ID) { - FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != 0x%X), ignoring SM24", sm24size, sdtahalfsize); - goto ret; // no error + int sm24size, sdtahalfsize; + + FLUID_LOG(FLUID_DBG, "Found SM24 chunk"); + if (chunk.size > size) + { + FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24"); + goto ret; // no error + } + + sdtahalfsize = sf->samplesize / 2; + /* + 1 byte in the case that half the size of smpl chunk is an odd value */ + sdtahalfsize += sdtahalfsize % 2; + sm24size = chunk.size; + + if (sdtahalfsize != sm24size) + { + FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != " + "0x%X), ignoring SM24", + sm24size, sdtahalfsize); + goto ret; // no error + } + + /* sample data24 follows */ + sf->sample24pos = fcbs->ftell(fd); + sf->sample24size = sm24size; } - - /* sample data24 follows */ - sf->sample24pos = fcbs->ftell (fd); - sf->sample24size = sm24size; } } - } - + ret: - FSKIP (size, fd, fcbs); - - return (OK); + FSKIP(size, fd, fcbs); + + return (OK); } -static int -pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk, - int * size, void * fd, const fluid_file_callbacks_t* fcbs) +static int pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size, void *fd, const fluid_file_callbacks_t *fcbs) { - unsigned int id; - const char *expstr; + unsigned int id; + const char *expstr; - expstr = CHNKIDSTR (expid); /* in case we need it */ + expstr = CHNKIDSTR(expid); /* in case we need it */ - READCHUNK (chunk, fd, fcbs); - *size -= 8; + READCHUNK(chunk, fd, fcbs); + *size -= 8; - if ((id = chunkid (chunk->id)) != expid) - return (gerr (ErrCorr, _("Expected" - " PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr)); + if ((id = chunkid(chunk->id)) != expid) + return (gerr(ErrCorr, _("Expected" + " PDTA sub-chunk \"%.4s\" found invalid id instead"), + expstr)); - if (chunk->size % reclen) /* valid chunk size? */ - return (gerr (ErrCorr, - _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, - reclen)); - if ((*size -= chunk->size) < 0) - return (gerr (ErrCorr, - _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr)); - return (OK); + if (chunk->size % reclen) /* valid chunk size? */ + return (gerr(ErrCorr, _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, reclen)); + if ((*size -= chunk->size) < 0) + return (gerr(ErrCorr, _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr)); + return (OK); } -static int -process_pdta (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - SFChunk chunk; + SFChunk chunk; - if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_phdr (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_phdr(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_pbag (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_pbag(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_pmod (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_pmod(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_pgen (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_pgen(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_ihdr (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_ihdr(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_ibag (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_ibag(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_imod (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_imod(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_igen (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_igen(chunk.size, sf, fd, fcbs)) + return (FAIL); - if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); - if (!load_shdr (chunk.size, sf, fd, fcbs)) - return (FAIL); + if (!pdtahelper(SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs)) + return (FAIL); + if (!load_shdr(chunk.size, sf, fd, fcbs)) + return (FAIL); - return (OK); + return (OK); } /* preset header loader */ -static int -load_phdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - int i, i2; - SFPreset *p, *pr = NULL; /* ptr to current & previous preset */ - unsigned short zndx, pzndx = 0; + int i, i2; + SFPreset *p, *pr = NULL; /* ptr to current & previous preset */ + unsigned short zndx, pzndx = 0; - if (size % SFPHDRSIZE || size == 0) - return (gerr (ErrCorr, _("Preset header chunk size is invalid"))); + if (size % SFPHDRSIZE || size == 0) + return (gerr(ErrCorr, _("Preset header chunk size is invalid"))); - i = size / SFPHDRSIZE - 1; - if (i == 0) - { /* at least one preset + term record */ - FLUID_LOG (FLUID_WARN, _("File contains no presets")); - FSKIP (SFPHDRSIZE, fd, fcbs); - return (OK); + i = size / SFPHDRSIZE - 1; + if (i == 0) + { /* at least one preset + term record */ + FLUID_LOG(FLUID_WARN, _("File contains no presets")); + FSKIP(SFPHDRSIZE, fd, fcbs); + return (OK); } - for (; i > 0; i--) - { /* load all preset headers */ - p = FLUID_NEW (SFPreset); - sf->preset = fluid_list_append (sf->preset, p); - p->zone = NULL; /* In case of failure, sfont_close can cleanup */ - READSTR (&p->name, fd, fcbs); /* possible read failure ^ */ - READW (p->prenum, fd, fcbs); - READW (p->bank, fd, fcbs); - READW (zndx, fd, fcbs); - READD (p->libr, fd, fcbs); - READD (p->genre, fd, fcbs); - READD (p->morph, fd, fcbs); + for (; i > 0; i--) + { /* load all preset headers */ + p = FLUID_NEW(SFPreset); + sf->preset = fluid_list_append(sf->preset, p); + p->zone = NULL; /* In case of failure, sfont_close can cleanup */ + READSTR(&p->name, fd, fcbs); /* possible read failure ^ */ + READW(p->prenum, fd, fcbs); + READW(p->bank, fd, fcbs); + READW(zndx, fd, fcbs); + READD(p->libr, fd, fcbs); + READD(p->genre, fd, fcbs); + READD(p->morph, fd, fcbs); - if (pr) - { /* not first preset? */ - if (zndx < pzndx) - return (gerr (ErrCorr, _("Preset header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - { - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - } - else if (zndx > 0) /* 1st preset, warn if ofs >0 */ - FLUID_LOG (FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx); - pr = p; /* update preset ptr */ - pzndx = zndx; + if (pr) + { /* not first preset? */ + if (zndx < pzndx) + return (gerr(ErrCorr, _("Preset header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + { + pr->zone = fluid_list_prepend(pr->zone, NULL); + } + } + else if (zndx > 0) /* 1st preset, warn if ofs >0 */ + FLUID_LOG(FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx); + pr = p; /* update preset ptr */ + pzndx = zndx; } - FSKIP (24, fd, fcbs); - READW (zndx, fd, fcbs); /* Read terminal generator index */ - FSKIP (12, fd, fcbs); + FSKIP(24, fd, fcbs); + READW(zndx, fd, fcbs); /* Read terminal generator index */ + FSKIP(12, fd, fcbs); - if (zndx < pzndx) - return (gerr (ErrCorr, _("Preset header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) + if (zndx < pzndx) + return (gerr(ErrCorr, _("Preset header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) { - pr->zone = fluid_list_prepend (pr->zone, NULL); + pr->zone = fluid_list_prepend(pr->zone, NULL); } - return (OK); + return (OK); } /* preset bag loader */ -static int -load_pbag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2; - SFZone *z, *pz = NULL; - unsigned short genndx, modndx; - unsigned short pgenndx = 0, pmodndx = 0; - unsigned short i; + fluid_list_t *p, *p2; + SFZone *z, *pz = NULL; + unsigned short genndx, modndx; + unsigned short pgenndx = 0, pmodndx = 0; + unsigned short i; - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr (ErrCorr, _("Preset bag chunk size is invalid"))); + if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ + return (gerr(ErrCorr, _("Preset bag chunk size is invalid"))); - p = sf->preset; - while (p) - { /* traverse through presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse preset's zones */ - if ((size -= SFBAGSIZE) < 0) - return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); - z = FLUID_NEW (SFZone); - p2->data = z; - z->gen = NULL; /* Init gen and mod before possible failure, */ - z->mod = NULL; /* to ensure proper cleanup (sfont_close) */ - READW (genndx, fd, fcbs); /* possible read failure ^ */ - READW (modndx, fd, fcbs); - z->instsamp = NULL; + p = sf->preset; + while (p) + { /* traverse through presets */ + p2 = ((SFPreset *)(p->data))->zone; + while (p2) + { /* traverse preset's zones */ + if ((size -= SFBAGSIZE) < 0) + return (gerr(ErrCorr, _("Preset bag chunk size mismatch"))); + z = FLUID_NEW(SFZone); + p2->data = z; + z->gen = NULL; /* Init gen and mod before possible failure, */ + z->mod = NULL; /* to ensure proper cleanup (sfont_close) */ + READW(genndx, fd, fcbs); /* possible read failure ^ */ + READW(modndx, fd, fcbs); + z->instsamp = NULL; - if (pz) - { /* if not first zone */ - if (genndx < pgenndx) - return (gerr (ErrCorr, - _("Preset bag generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, - _("Preset bag modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - } - pz = z; /* update previous zone ptr */ - pgenndx = genndx; /* update previous zone gen index */ - pmodndx = modndx; /* update previous zone mod index */ - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); + if (pz) + { /* if not first zone */ + if (genndx < pgenndx) + return (gerr(ErrCorr, _("Preset bag generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr(ErrCorr, _("Preset bag modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend(pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend(pz->mod, NULL); + } + pz = z; /* update previous zone ptr */ + pgenndx = genndx; /* update previous zone gen index */ + pmodndx = modndx; /* update previous zone mod index */ + p2 = fluid_list_next(p2); + } + p = fluid_list_next(p); } - size -= SFBAGSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset bag chunk size mismatch"))); + size -= SFBAGSIZE; + if (size != 0) + return (gerr(ErrCorr, _("Preset bag chunk size mismatch"))); - READW (genndx, fd, fcbs); - READW (modndx, fd, fcbs); + READW(genndx, fd, fcbs); + READW(modndx, fd, fcbs); - if (!pz) + if (!pz) { - if (genndx > 0) - FLUID_LOG (FLUID_WARN, _("No preset generators and terminal index not 0")); - if (modndx > 0) - FLUID_LOG (FLUID_WARN, _("No preset modulators and terminal index not 0")); - return (OK); + if (genndx > 0) + FLUID_LOG(FLUID_WARN, _("No preset generators and terminal index not 0")); + if (modndx > 0) + FLUID_LOG(FLUID_WARN, _("No preset modulators and terminal index not 0")); + return (OK); } - if (genndx < pgenndx) - return (gerr (ErrCorr, _("Preset bag generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, _("Preset bag modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); + if (genndx < pgenndx) + return (gerr(ErrCorr, _("Preset bag generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr(ErrCorr, _("Preset bag modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend(pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend(pz->mod, NULL); - return (OK); + return (OK); } /* preset modulator loader */ -static int -load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2, *p3; - SFMod *m; + fluid_list_t *p, *p2, *p3; + SFMod *m; - p = sf->preset; - while (p) - { /* traverse through all presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse this preset's zones */ - p3 = ((SFZone *) (p2->data))->mod; - while (p3) - { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) - return (gerr (ErrCorr, - _("Preset modulator chunk size mismatch"))); - m = FLUID_NEW (SFMod); - p3->data = m; - READW (m->src, fd, fcbs); - READW (m->dest, fd, fcbs); - READW (m->amount, fd, fcbs); - READW (m->amtsrc, fd, fcbs); - READW (m->trans, fd, fcbs); - p3 = fluid_list_next (p3); - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); + p = sf->preset; + while (p) + { /* traverse through all presets */ + p2 = ((SFPreset *)(p->data))->zone; + while (p2) + { /* traverse this preset's zones */ + p3 = ((SFZone *)(p2->data))->mod; + while (p3) + { /* load zone's modulators */ + if ((size -= SFMODSIZE) < 0) + return (gerr(ErrCorr, _("Preset modulator chunk size mismatch"))); + m = FLUID_NEW(SFMod); + p3->data = m; + READW(m->src, fd, fcbs); + READW(m->dest, fd, fcbs); + READW(m->amount, fd, fcbs); + READW(m->amtsrc, fd, fcbs); + READW(m->trans, fd, fcbs); + p3 = fluid_list_next(p3); + } + p2 = fluid_list_next(p2); + } + p = fluid_list_next(p); } - /* - If there isn't even a terminal record - Hmmm, the specs say there should be one, but.. - */ - if (size == 0) + /* + If there isn't even a terminal record + Hmmm, the specs say there should be one, but.. + */ + if (size == 0) + return (OK); + + size -= SFMODSIZE; + if (size != 0) + return (gerr(ErrCorr, _("Preset modulator chunk size mismatch"))); + FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ + return (OK); - - size -= SFMODSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset modulator chunk size mismatch"))); - FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */ - - return (OK); } /* ------------------------------------------------------------------- @@ -808,909 +871,883 @@ load_pmod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) * if a generator follows an instrument discard it * if a duplicate generator exists replace previous one * ------------------------------------------------------------------- */ -static int -load_pgen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; - SFZone *z; - SFGen *g; - SFGenAmount genval; - unsigned short genid; - int level, skip, drop, gzone, discarded; + fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; + SFZone *z; + SFGen *g; + SFGenAmount genval; + unsigned short genid; + int level, skip, drop, gzone, discarded; - p = sf->preset; - while (p) - { /* traverse through all presets */ - gzone = FALSE; - discarded = FALSE; - p2 = ((SFPreset *) (p->data))->zone; - if (p2) - hz = &p2; - while (p2) - { /* traverse preset's zones */ - level = 0; - z = (SFZone *) (p2->data); - p3 = z->gen; - while (p3) - { /* load zone's generators */ - dup = NULL; - skip = FALSE; - drop = FALSE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Preset generator chunk size mismatch"))); + p = sf->preset; + while (p) + { /* traverse through all presets */ + gzone = FALSE; + discarded = FALSE; + p2 = ((SFPreset *)(p->data))->zone; + if (p2) + hz = &p2; + while (p2) + { /* traverse preset's zones */ + level = 0; + z = (SFZone *)(p2->data); + p3 = z->gen; + while (p3) + { /* load zone's generators */ + dup = NULL; + skip = FALSE; + drop = FALSE; + if ((size -= SFGENSIZE) < 0) + return (gerr(ErrCorr, _("Preset generator chunk size mismatch"))); - READW (genid, fd, fcbs); + READW(genid, fd, fcbs); - if (genid == Gen_KeyRange) - { /* nothing precedes */ - if (level == 0) - { - level = 1; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_VelRange) - { /* only KeyRange precedes */ - if (level <= 1) - { - level = 2; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_Instrument) - { /* inst is last gen */ - level = 3; - READW (genval.uword, fd, fcbs); - ((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1); - break; /* break out of generator loop */ - } - else - { - level = 2; - if (gen_validp (genid)) - { /* generator valid? */ - READW (genval.sword, fd, fcbs); - dup = gen_inlist (genid, z->gen); - } - else - skip = TRUE; - } + if (genid == Gen_KeyRange) + { /* nothing precedes */ + if (level == 0) + { + level = 1; + READB(genval.range.lo, fd, fcbs); + READB(genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_VelRange) + { /* only KeyRange precedes */ + if (level <= 1) + { + level = 2; + READB(genval.range.lo, fd, fcbs); + READB(genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_Instrument) + { /* inst is last gen */ + level = 3; + READW(genval.uword, fd, fcbs); + ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1); + break; /* break out of generator loop */ + } + else + { + level = 2; + if (gen_validp(genid)) + { /* generator valid? */ + READW(genval.sword, fd, fcbs); + dup = gen_inlist(genid, z->gen); + } + else + skip = TRUE; + } - if (!skip) - { - if (!dup) - { /* if gen ! dup alloc new */ - g = FLUID_NEW (SFGen); - p3->data = g; - g->id = genid; - } - else - { - g = (SFGen *) (dup->data); /* ptr to orig gen */ - drop = TRUE; - } - g->amount = genval; - } - else - { /* Skip this generator */ - discarded = TRUE; - drop = TRUE; - FSKIPW (fd, fcbs); - } + if (!skip) + { + if (!dup) + { /* if gen ! dup alloc new */ + g = FLUID_NEW(SFGen); + p3->data = g; + g->id = genid; + } + else + { + g = (SFGen *)(dup->data); /* ptr to orig gen */ + drop = TRUE; + } + g->amount = genval; + } + else + { /* Skip this generator */ + discarded = TRUE; + drop = TRUE; + FSKIPW(fd, fcbs); + } - if (!drop) - p3 = fluid_list_next (p3); /* next gen */ - else - SLADVREM (z->gen, p3); /* drop place holder */ + if (!drop) + p3 = fluid_list_next(p3); /* next gen */ + else + SLADVREM(z->gen, p3); /* drop place holder */ - } /* generator loop */ + } /* generator loop */ - if (level == 3) - SLADVREM (z->gen, p3); /* zone has inst? */ - else - { /* congratulations its a global zone */ - if (!gzone) - { /* Prior global zones? */ - gzone = TRUE; + if (level == 3) + SLADVREM(z->gen, p3); /* zone has inst? */ + else + { /* congratulations its a global zone */ + if (!gzone) + { /* Prior global zones? */ + gzone = TRUE; - /* if global zone is not 1st zone, relocate */ - if (*hz != p2) - { - void* save = p2->data; - FLUID_LOG (FLUID_WARN, - _("Preset \"%s\": Global zone is not first zone"), - ((SFPreset *) (p->data))->name); - SLADVREM (*hz, p2); - *hz = fluid_list_prepend (*hz, save); - continue; - } - } - else - { /* previous global zone exists, discard */ - FLUID_LOG (FLUID_WARN, - _("Preset \"%s\": Discarding invalid global zone"), - ((SFPreset *) (p->data))->name); - sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); - } - } + /* if global zone is not 1st zone, relocate */ + if (*hz != p2) + { + void *save = p2->data; + FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Global zone is not first zone"), + ((SFPreset *)(p->data))->name); + SLADVREM(*hz, p2); + *hz = fluid_list_prepend(*hz, save); + continue; + } + } + else + { /* previous global zone exists, discard */ + FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Discarding invalid global zone"), + ((SFPreset *)(p->data))->name); + sfont_zone_delete(sf, hz, (SFZone *)(p2->data)); + } + } - while (p3) - { /* Kill any zones following an instrument */ - discarded = TRUE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Preset generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); - SLADVREM (z->gen, p3); - } + while (p3) + { /* Kill any zones following an instrument */ + discarded = TRUE; + if ((size -= SFGENSIZE) < 0) + return (gerr(ErrCorr, _("Preset generator chunk size mismatch"))); + FSKIP(SFGENSIZE, fd, fcbs); + SLADVREM(z->gen, p3); + } - p2 = fluid_list_next (p2); /* next zone */ - } - if (discarded) - FLUID_LOG(FLUID_WARN, - _("Preset \"%s\": Some invalid generators were discarded"), - ((SFPreset *) (p->data))->name); - p = fluid_list_next (p); + p2 = fluid_list_next(p2); /* next zone */ + } + if (discarded) + FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Some invalid generators were discarded"), + ((SFPreset *)(p->data))->name); + p = fluid_list_next(p); } - /* in case there isn't a terminal record */ - if (size == 0) + /* in case there isn't a terminal record */ + if (size == 0) + return (OK); + + size -= SFGENSIZE; + if (size != 0) + return (gerr(ErrCorr, _("Preset generator chunk size mismatch"))); + FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ + return (OK); - - size -= SFGENSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Preset generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */ - - return (OK); } /* instrument header loader */ -static int -load_ihdr (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - int i, i2; - SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ - unsigned short zndx, pzndx = 0; + int i, i2; + SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ + unsigned short zndx, pzndx = 0; - if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ - return (gerr (ErrCorr, _("Instrument header has invalid size"))); + if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ + return (gerr(ErrCorr, _("Instrument header has invalid size"))); - size = size / SFIHDRSIZE - 1; - if (size == 0) - { /* at least one preset + term record */ - FLUID_LOG (FLUID_WARN, _("File contains no instruments")); - FSKIP (SFIHDRSIZE, fd, fcbs); - return (OK); + size = size / SFIHDRSIZE - 1; + if (size == 0) + { /* at least one preset + term record */ + FLUID_LOG(FLUID_WARN, _("File contains no instruments")); + FSKIP(SFIHDRSIZE, fd, fcbs); + return (OK); } - for (i = 0; i < size; i++) - { /* load all instrument headers */ - p = FLUID_NEW (SFInst); - sf->inst = fluid_list_append (sf->inst, p); - p->zone = NULL; /* For proper cleanup if fail (sfont_close) */ - READSTR (&p->name, fd, fcbs); /* Possible read failure ^ */ - READW (zndx, fd, fcbs); + for (i = 0; i < size; i++) + { /* load all instrument headers */ + p = FLUID_NEW(SFInst); + sf->inst = fluid_list_append(sf->inst, p); + p->zone = NULL; /* For proper cleanup if fail (sfont_close) */ + READSTR(&p->name, fd, fcbs); /* Possible read failure ^ */ + READW(zndx, fd, fcbs); - if (pr) - { /* not first instrument? */ - if (zndx < pzndx) - return (gerr (ErrCorr, - _("Instrument header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - pr->zone = fluid_list_prepend (pr->zone, NULL); - } - else if (zndx > 0) /* 1st inst, warn if ofs >0 */ - FLUID_LOG (FLUID_WARN, _("%d instrument zones not referenced, discarding"), - zndx); - pzndx = zndx; - pr = p; /* update instrument ptr */ + if (pr) + { /* not first instrument? */ + if (zndx < pzndx) + return (gerr(ErrCorr, _("Instrument header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + pr->zone = fluid_list_prepend(pr->zone, NULL); + } + else if (zndx > 0) /* 1st inst, warn if ofs >0 */ + FLUID_LOG(FLUID_WARN, _("%d instrument zones not referenced, discarding"), zndx); + pzndx = zndx; + pr = p; /* update instrument ptr */ } - FSKIP (20, fd, fcbs); - READW (zndx, fd, fcbs); + FSKIP(20, fd, fcbs); + READW(zndx, fd, fcbs); - if (zndx < pzndx) - return (gerr (ErrCorr, _("Instrument header indices not monotonic"))); - i2 = zndx - pzndx; - while (i2--) - pr->zone = fluid_list_prepend (pr->zone, NULL); + if (zndx < pzndx) + return (gerr(ErrCorr, _("Instrument header indices not monotonic"))); + i2 = zndx - pzndx; + while (i2--) + pr->zone = fluid_list_prepend(pr->zone, NULL); - return (OK); + return (OK); } /* instrument bag loader */ -static int -load_ibag (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2; - SFZone *z, *pz = NULL; - unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0; - int i; + fluid_list_t *p, *p2; + SFZone *z, *pz = NULL; + unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0; + int i; - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr (ErrCorr, _("Instrument bag chunk size is invalid"))); + if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ + return (gerr(ErrCorr, _("Instrument bag chunk size is invalid"))); - p = sf->inst; - while (p) - { /* traverse through inst */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* load this inst's zones */ - if ((size -= SFBAGSIZE) < 0) - return (gerr (ErrCorr, _("Instrument bag chunk size mismatch"))); - z = FLUID_NEW (SFZone); - p2->data = z; - z->gen = NULL; /* In case of failure, */ - z->mod = NULL; /* sfont_close can clean up */ - READW (genndx, fd, fcbs); /* READW = possible read failure */ - READW (modndx, fd, fcbs); - z->instsamp = NULL; + p = sf->inst; + while (p) + { /* traverse through inst */ + p2 = ((SFInst *)(p->data))->zone; + while (p2) + { /* load this inst's zones */ + if ((size -= SFBAGSIZE) < 0) + return (gerr(ErrCorr, _("Instrument bag chunk size mismatch"))); + z = FLUID_NEW(SFZone); + p2->data = z; + z->gen = NULL; /* In case of failure, */ + z->mod = NULL; /* sfont_close can clean up */ + READW(genndx, fd, fcbs); /* READW = possible read failure */ + READW(modndx, fd, fcbs); + z->instsamp = NULL; - if (pz) - { /* if not first zone */ - if (genndx < pgenndx) - return (gerr (ErrCorr, - _("Instrument generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, - _("Instrument modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); - } - pz = z; /* update previous zone ptr */ - pgenndx = genndx; - pmodndx = modndx; - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); + if (pz) + { /* if not first zone */ + if (genndx < pgenndx) + return (gerr(ErrCorr, _("Instrument generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr(ErrCorr, _("Instrument modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend(pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend(pz->mod, NULL); + } + pz = z; /* update previous zone ptr */ + pgenndx = genndx; + pmodndx = modndx; + p2 = fluid_list_next(p2); + } + p = fluid_list_next(p); } - size -= SFBAGSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Instrument chunk size mismatch"))); + size -= SFBAGSIZE; + if (size != 0) + return (gerr(ErrCorr, _("Instrument chunk size mismatch"))); - READW (genndx, fd, fcbs); - READW (modndx, fd, fcbs); + READW(genndx, fd, fcbs); + READW(modndx, fd, fcbs); - if (!pz) - { /* in case that all are no zoners */ - if (genndx > 0) - FLUID_LOG (FLUID_WARN, - _("No instrument generators and terminal index not 0")); - if (modndx > 0) - FLUID_LOG (FLUID_WARN, - _("No instrument modulators and terminal index not 0")); - return (OK); + if (!pz) + { /* in case that all are no zoners */ + if (genndx > 0) + FLUID_LOG(FLUID_WARN, _("No instrument generators and terminal index not 0")); + if (modndx > 0) + FLUID_LOG(FLUID_WARN, _("No instrument modulators and terminal index not 0")); + return (OK); } - if (genndx < pgenndx) - return (gerr (ErrCorr, _("Instrument generator indices not monotonic"))); - if (modndx < pmodndx) - return (gerr (ErrCorr, _("Instrument modulator indices not monotonic"))); - i = genndx - pgenndx; - while (i--) - pz->gen = fluid_list_prepend (pz->gen, NULL); - i = modndx - pmodndx; - while (i--) - pz->mod = fluid_list_prepend (pz->mod, NULL); + if (genndx < pgenndx) + return (gerr(ErrCorr, _("Instrument generator indices not monotonic"))); + if (modndx < pmodndx) + return (gerr(ErrCorr, _("Instrument modulator indices not monotonic"))); + i = genndx - pgenndx; + while (i--) + pz->gen = fluid_list_prepend(pz->gen, NULL); + i = modndx - pmodndx; + while (i--) + pz->mod = fluid_list_prepend(pz->mod, NULL); - return (OK); + return (OK); } /* instrument modulator loader */ -static int -load_imod (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2, *p3; - SFMod *m; + fluid_list_t *p, *p2, *p3; + SFMod *m; - p = sf->inst; - while (p) - { /* traverse through all inst */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* traverse this inst's zones */ - p3 = ((SFZone *) (p2->data))->mod; - while (p3) - { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) - return (gerr (ErrCorr, - _("Instrument modulator chunk size mismatch"))); - m = FLUID_NEW (SFMod); - p3->data = m; - READW (m->src, fd, fcbs); - READW (m->dest, fd, fcbs); - READW (m->amount, fd, fcbs); - READW (m->amtsrc, fd, fcbs); - READW (m->trans, fd, fcbs); - p3 = fluid_list_next (p3); - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); + p = sf->inst; + while (p) + { /* traverse through all inst */ + p2 = ((SFInst *)(p->data))->zone; + while (p2) + { /* traverse this inst's zones */ + p3 = ((SFZone *)(p2->data))->mod; + while (p3) + { /* load zone's modulators */ + if ((size -= SFMODSIZE) < 0) + return (gerr(ErrCorr, _("Instrument modulator chunk size mismatch"))); + m = FLUID_NEW(SFMod); + p3->data = m; + READW(m->src, fd, fcbs); + READW(m->dest, fd, fcbs); + READW(m->amount, fd, fcbs); + READW(m->amtsrc, fd, fcbs); + READW(m->trans, fd, fcbs); + p3 = fluid_list_next(p3); + } + p2 = fluid_list_next(p2); + } + p = fluid_list_next(p); } - /* - If there isn't even a terminal record - Hmmm, the specs say there should be one, but.. - */ - if (size == 0) + /* + If there isn't even a terminal record + Hmmm, the specs say there should be one, but.. + */ + if (size == 0) + return (OK); + + size -= SFMODSIZE; + if (size != 0) + return (gerr(ErrCorr, _("Instrument modulator chunk size mismatch"))); + FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ + return (OK); - - size -= SFMODSIZE; - if (size != 0) - return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch"))); - FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */ - - return (OK); } /* load instrument generators (see load_pgen for loading rules) */ -static int -load_igen (int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; - SFZone *z; - SFGen *g; - SFGenAmount genval; - unsigned short genid; - int level, skip, drop, gzone, discarded; + fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; + SFZone *z; + SFGen *g; + SFGenAmount genval; + unsigned short genid; + int level, skip, drop, gzone, discarded; - p = sf->inst; - while (p) - { /* traverse through all instruments */ - gzone = FALSE; - discarded = FALSE; - p2 = ((SFInst *) (p->data))->zone; - if (p2) - hz = &p2; - while (p2) - { /* traverse this instrument's zones */ - level = 0; - z = (SFZone *) (p2->data); - p3 = z->gen; - while (p3) - { /* load zone's generators */ - dup = NULL; - skip = FALSE; - drop = FALSE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); + p = sf->inst; + while (p) + { /* traverse through all instruments */ + gzone = FALSE; + discarded = FALSE; + p2 = ((SFInst *)(p->data))->zone; + if (p2) + hz = &p2; + while (p2) + { /* traverse this instrument's zones */ + level = 0; + z = (SFZone *)(p2->data); + p3 = z->gen; + while (p3) + { /* load zone's generators */ + dup = NULL; + skip = FALSE; + drop = FALSE; + if ((size -= SFGENSIZE) < 0) + return (gerr(ErrCorr, _("IGEN chunk size mismatch"))); - READW (genid, fd, fcbs); + READW(genid, fd, fcbs); - if (genid == Gen_KeyRange) - { /* nothing precedes */ - if (level == 0) - { - level = 1; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_VelRange) - { /* only KeyRange precedes */ - if (level <= 1) - { - level = 2; - READB (genval.range.lo, fd, fcbs); - READB (genval.range.hi, fd, fcbs); - } - else - skip = TRUE; - } - else if (genid == Gen_SampleId) - { /* sample is last gen */ - level = 3; - READW (genval.uword, fd, fcbs); - ((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1); - break; /* break out of generator loop */ - } - else - { - level = 2; - if (gen_valid (genid)) - { /* gen valid? */ - READW (genval.sword, fd, fcbs); - dup = gen_inlist (genid, z->gen); - } - else - skip = TRUE; - } + if (genid == Gen_KeyRange) + { /* nothing precedes */ + if (level == 0) + { + level = 1; + READB(genval.range.lo, fd, fcbs); + READB(genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_VelRange) + { /* only KeyRange precedes */ + if (level <= 1) + { + level = 2; + READB(genval.range.lo, fd, fcbs); + READB(genval.range.hi, fd, fcbs); + } + else + skip = TRUE; + } + else if (genid == Gen_SampleId) + { /* sample is last gen */ + level = 3; + READW(genval.uword, fd, fcbs); + ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1); + break; /* break out of generator loop */ + } + else + { + level = 2; + if (gen_valid(genid)) + { /* gen valid? */ + READW(genval.sword, fd, fcbs); + dup = gen_inlist(genid, z->gen); + } + else + skip = TRUE; + } - if (!skip) - { - if (!dup) - { /* if gen ! dup alloc new */ - g = FLUID_NEW (SFGen); - p3->data = g; - g->id = genid; - } - else - { - g = (SFGen *) (dup->data); - drop = TRUE; - } - g->amount = genval; - } - else - { /* skip this generator */ - discarded = TRUE; - drop = TRUE; - FSKIPW (fd, fcbs); - } + if (!skip) + { + if (!dup) + { /* if gen ! dup alloc new */ + g = FLUID_NEW(SFGen); + p3->data = g; + g->id = genid; + } + else + { + g = (SFGen *)(dup->data); + drop = TRUE; + } + g->amount = genval; + } + else + { /* skip this generator */ + discarded = TRUE; + drop = TRUE; + FSKIPW(fd, fcbs); + } - if (!drop) - p3 = fluid_list_next (p3); /* next gen */ - else - SLADVREM (z->gen, p3); + if (!drop) + p3 = fluid_list_next(p3); /* next gen */ + else + SLADVREM(z->gen, p3); - } /* generator loop */ + } /* generator loop */ - if (level == 3) - SLADVREM (z->gen, p3); /* zone has sample? */ - else - { /* its a global zone */ - if (!gzone) - { - gzone = TRUE; + if (level == 3) + SLADVREM(z->gen, p3); /* zone has sample? */ + else + { /* its a global zone */ + if (!gzone) + { + gzone = TRUE; - /* if global zone is not 1st zone, relocate */ - if (*hz != p2) - { - void* save = p2->data; - FLUID_LOG (FLUID_WARN, - _("Instrument \"%s\": Global zone is not first zone"), - ((SFPreset *) (p->data))->name); - SLADVREM (*hz, p2); - *hz = fluid_list_prepend (*hz, save); - continue; - } - } - else - { /* previous global zone exists, discard */ - FLUID_LOG (FLUID_WARN, - _("Instrument \"%s\": Discarding invalid global zone"), - ((SFInst *) (p->data))->name); - sfont_zone_delete (sf, hz, (SFZone *) (p2->data)); - } - } + /* if global zone is not 1st zone, relocate */ + if (*hz != p2) + { + void *save = p2->data; + FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Global zone is not first zone"), + ((SFPreset *)(p->data))->name); + SLADVREM(*hz, p2); + *hz = fluid_list_prepend(*hz, save); + continue; + } + } + else + { /* previous global zone exists, discard */ + FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Discarding invalid global zone"), + ((SFInst *)(p->data))->name); + sfont_zone_delete(sf, hz, (SFZone *)(p2->data)); + } + } - while (p3) - { /* Kill any zones following a sample */ - discarded = TRUE; - if ((size -= SFGENSIZE) < 0) - return (gerr (ErrCorr, - _("Instrument generator chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); - SLADVREM (z->gen, p3); - } + while (p3) + { /* Kill any zones following a sample */ + discarded = TRUE; + if ((size -= SFGENSIZE) < 0) + return (gerr(ErrCorr, _("Instrument generator chunk size mismatch"))); + FSKIP(SFGENSIZE, fd, fcbs); + SLADVREM(z->gen, p3); + } - p2 = fluid_list_next (p2); /* next zone */ - } - if (discarded) - FLUID_LOG(FLUID_WARN, - _("Instrument \"%s\": Some invalid generators were discarded"), - ((SFInst *) (p->data))->name); - p = fluid_list_next (p); + p2 = fluid_list_next(p2); /* next zone */ + } + if (discarded) + FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Some invalid generators were discarded"), + ((SFInst *)(p->data))->name); + p = fluid_list_next(p); } - /* for those non-terminal record cases, grr! */ - if (size == 0) + /* for those non-terminal record cases, grr! */ + if (size == 0) + return (OK); + + size -= SFGENSIZE; + if (size != 0) + return (gerr(ErrCorr, _("IGEN chunk size mismatch"))); + FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ + return (OK); - - size -= SFGENSIZE; - if (size != 0) - return (gerr (ErrCorr, _("IGEN chunk size mismatch"))); - FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */ - - return (OK); } /* sample header loader */ -static int -load_shdr (unsigned int size, SFData * sf, void * fd, const fluid_file_callbacks_t* fcbs) +static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { - unsigned int i; - SFSample *p; + unsigned int i; + SFSample *p; - if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ - return (gerr (ErrCorr, _("Sample header has invalid size"))); + if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ + return (gerr(ErrCorr, _("Sample header has invalid size"))); - size = size / SFSHDRSIZE - 1; - if (size == 0) - { /* at least one sample + term record? */ - FLUID_LOG (FLUID_WARN, _("File contains no samples")); - FSKIP (SFSHDRSIZE, fd, fcbs); - return (OK); + size = size / SFSHDRSIZE - 1; + if (size == 0) + { /* at least one sample + term record? */ + FLUID_LOG(FLUID_WARN, _("File contains no samples")); + FSKIP(SFSHDRSIZE, fd, fcbs); + return (OK); } - /* load all sample headers */ - for (i = 0; i < size; i++) + /* load all sample headers */ + for (i = 0; i < size; i++) { - p = FLUID_NEW (SFSample); - sf->sample = fluid_list_append (sf->sample, p); - READSTR (&p->name, fd, fcbs); - READD (p->start, fd, fcbs); - READD (p->end, fd, fcbs); /* - end, loopstart and loopend */ - READD (p->loopstart, fd, fcbs); /* - will be checked and turned into */ - READD (p->loopend, fd, fcbs); /* - offsets in fixup_sample() */ - READD (p->samplerate, fd, fcbs); - READB (p->origpitch, fd, fcbs); - READB (p->pitchadj, fd, fcbs); - FSKIPW (fd, fcbs); /* skip sample link */ - READW (p->sampletype, fd, fcbs); - p->samfile = 0; + p = FLUID_NEW(SFSample); + sf->sample = fluid_list_append(sf->sample, p); + READSTR(&p->name, fd, fcbs); + READD(p->start, fd, fcbs); + READD(p->end, fd, fcbs); /* - end, loopstart and loopend */ + READD(p->loopstart, fd, fcbs); /* - will be checked and turned into */ + READD(p->loopend, fd, fcbs); /* - offsets in fixup_sample() */ + READD(p->samplerate, fd, fcbs); + READB(p->origpitch, fd, fcbs); + READB(p->pitchadj, fd, fcbs); + FSKIPW(fd, fcbs); /* skip sample link */ + READW(p->sampletype, fd, fcbs); + p->samfile = 0; } - FSKIP (SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */ + FSKIP(SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */ - return (OK); + return (OK); } /* "fixup" (inst # -> inst ptr) instrument references in preset list */ -static int -fixup_pgen (SFData * sf) +static int fixup_pgen(SFData *sf) { - fluid_list_t *p, *p2, *p3; - SFZone *z; - int i; + fluid_list_t *p, *p2, *p3; + SFZone *z; + int i; - p = sf->preset; - while (p) + p = sf->preset; + while (p) { - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* traverse this preset's zones */ - z = (SFZone *) (p2->data); - if ((i = FLUID_POINTER_TO_INT (z->instsamp))) - { /* load instrument # */ - p3 = fluid_list_nth (sf->inst, i - 1); - if (!p3) - return (gerr (ErrCorr, - _("Preset %03d %03d: Invalid instrument reference"), - ((SFPreset *) (p->data))->bank, - ((SFPreset *) (p->data))->prenum)); - z->instsamp = p3; - } - else - z->instsamp = NULL; - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); + p2 = ((SFPreset *)(p->data))->zone; + while (p2) + { /* traverse this preset's zones */ + z = (SFZone *)(p2->data); + if ((i = FLUID_POINTER_TO_INT(z->instsamp))) + { /* load instrument # */ + p3 = fluid_list_nth(sf->inst, i - 1); + if (!p3) + return (gerr(ErrCorr, _("Preset %03d %03d: Invalid instrument reference"), + ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum)); + z->instsamp = p3; + } + else + z->instsamp = NULL; + p2 = fluid_list_next(p2); + } + p = fluid_list_next(p); } - return (OK); + return (OK); } /* "fixup" (sample # -> sample ptr) sample references in instrument list */ -static int -fixup_igen (SFData * sf) +static int fixup_igen(SFData *sf) { - fluid_list_t *p, *p2, *p3; - SFZone *z; - int i; + fluid_list_t *p, *p2, *p3; + SFZone *z; + int i; - p = sf->inst; - while (p) + p = sf->inst; + while (p) { - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* traverse instrument's zones */ - z = (SFZone *) (p2->data); - if ((i = FLUID_POINTER_TO_INT (z->instsamp))) - { /* load sample # */ - p3 = fluid_list_nth (sf->sample, i - 1); - if (!p3) - return (gerr (ErrCorr, - _("Instrument \"%s\": Invalid sample reference"), - ((SFInst *) (p->data))->name)); - z->instsamp = p3; - } - p2 = fluid_list_next (p2); - } - p = fluid_list_next (p); + p2 = ((SFInst *)(p->data))->zone; + while (p2) + { /* traverse instrument's zones */ + z = (SFZone *)(p2->data); + if ((i = FLUID_POINTER_TO_INT(z->instsamp))) + { /* load sample # */ + p3 = fluid_list_nth(sf->sample, i - 1); + if (!p3) + return (gerr(ErrCorr, _("Instrument \"%s\": Invalid sample reference"), + ((SFInst *)(p->data))->name)); + z->instsamp = p3; + } + p2 = fluid_list_next(p2); + } + p = fluid_list_next(p); } - return (OK); + return (OK); } /* convert sample end, loopstart and loopend to offsets and check if valid */ -static int -fixup_sample (SFData * sf) +static int fixup_sample(SFData *sf) { - fluid_list_t *p; - SFSample *sam; - int invalid_loops=FALSE; - int invalid_loopstart; - int invalid_loopend, loopend_end_mismatch; - unsigned int total_bytes = sf->samplesize; - unsigned int total_samples = total_bytes / sizeof(short); + fluid_list_t *p; + SFSample *sam; + int invalid_loops = FALSE; + int invalid_loopstart; + int invalid_loopend, loopend_end_mismatch; + unsigned int total_bytes = sf->samplesize; + unsigned int total_samples = total_bytes / sizeof(short); - p = sf->sample; - while (p) + p = sf->sample; + while (p) { - unsigned int max_end; + unsigned int max_end; - sam = (SFSample *) (p->data); + sam = (SFSample *)(p->data); - /* Standard SoundFont files (SF2) use sample word indices for sample start and end pointers, - * but SF3 files with Ogg Vorbis compression use byte indices for start and end. */ - max_end = (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) ? total_bytes : total_samples; + /* Standard SoundFont files (SF2) use sample word indices for sample start and end pointers, + * but SF3 files with Ogg Vorbis compression use byte indices for start and end. */ + max_end = (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) ? total_bytes : total_samples; - /* ROM samples are unusable for us by definition, so simply ignore them. */ - if (sam->sampletype & FLUID_SAMPLETYPE_ROM) - { - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - goto next_sample; - } + /* ROM samples are unusable for us by definition, so simply ignore them. */ + if (sam->sampletype & FLUID_SAMPLETYPE_ROM) + { + sam->start = sam->end = sam->loopstart = sam->loopend = 0; + goto next_sample; + } - /* If end is over the sample data chunk or sam start is greater than 4 - * less than the end (at least 4 samples). - * - * FIXME: where does this number 4 come from? And do we need a different number for SF3 files? - * Maybe we should check for the minimum Ogg Vorbis headers size? */ - if ((sam->end > max_end) || (sam->start > (sam->end - 4))) - { - FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid," - " disabling and will not be saved"), sam->name); - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - goto next_sample; - } - - /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop */ - invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); - /* while loopend is the first point AFTER the last sample of the loop. - * this is as it should be. however we cannot be sure whether any of sam.loopend or sam.end - * is correct. hours of thinking through this have concluded, that it would be best practice - * to mangle with loops as little as necessary by only making sure loopend is within - * max_end. incorrect soundfont shall preferably fail loudly. */ - invalid_loopend = (sam->loopend > max_end) || (sam->loopstart >= sam->loopend); - - loopend_end_mismatch = (sam->loopend > sam->end); + /* If end is over the sample data chunk or sam start is greater than 4 + * less than the end (at least 4 samples). + * + * FIXME: where does this number 4 come from? And do we need a different number for SF3 + * files? + * Maybe we should check for the minimum Ogg Vorbis headers size? */ + if ((sam->end > max_end) || (sam->start > (sam->end - 4))) + { + FLUID_LOG(FLUID_WARN, _("Sample '%s' start/end file positions are invalid," + " disabling and will not be saved"), + sam->name); + sam->start = sam->end = sam->loopstart = sam->loopend = 0; + goto next_sample; + } - if (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) - { + /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop + */ + invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); + /* while loopend is the first point AFTER the last sample of the loop. + * this is as it should be. however we cannot be sure whether any of sam.loopend or sam.end + * is correct. hours of thinking through this have concluded, that it would be best practice + * to mangle with loops as little as necessary by only making sure loopend is within + * max_end. incorrect soundfont shall preferably fail loudly. */ + invalid_loopend = (sam->loopend > max_end) || (sam->loopstart >= sam->loopend); + + loopend_end_mismatch = (sam->loopend > sam->end); + + if (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) + { /* * compressed samples get fixed up after decompression - * - * however we cant use the logic below, because uncompressed samples are stored in individual buffers + * + * however we cant use the logic below, because uncompressed samples are stored in + * individual buffers */ } - else if (invalid_loopstart || invalid_loopend || loopend_end_mismatch) /* loop is fowled?? (cluck cluck :) */ - { + else if (invalid_loopstart || invalid_loopend || + loopend_end_mismatch) /* loop is fowled?? (cluck cluck :) */ + { /* though illegal, loopend may be set to loopstart to disable loop */ /* is it worth informing the user? */ invalid_loops |= (sam->loopend != sam->loopstart); - - /* force incorrect loop points into the sample range, ignore padding */ - if(invalid_loopstart) - { - FLUID_LOG (FLUID_DBG, _("Sample '%s' has unusable loop start '%d'," - " setting to sample start at '%d'"), sam->name, sam->loopstart, sam->start); - sam->loopstart = sam->start; - } - - if(invalid_loopend) - { - FLUID_LOG (FLUID_DBG, _("Sample '%s' has unusable loop stop '%d'," - " setting to sample stop at '%d'"), sam->name, sam->loopend, sam->end); - /* since at this time sam->end points after valid sample data (will correct that few lines below), - * set loopend to that first invalid sample, since it should never be played, but instead the last - * valid sample will be played */ - sam->loopend = sam->end; - } - else if(loopend_end_mismatch) - { - FLUID_LOG (FLUID_DBG, _("Sample '%s' has invalid loop stop '%d'," - " sample stop at '%d', using it anyway"), sam->name, sam->loopend, sam->end); - } - } - /* convert sample end, loopstart, loopend to offsets from sam->start */ - sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */ - sam->loopstart -= sam->start; - sam->loopend -= sam->start; + /* force incorrect loop points into the sample range, ignore padding */ + if (invalid_loopstart) + { + FLUID_LOG(FLUID_DBG, _("Sample '%s' has unusable loop start '%d'," + " setting to sample start at '%d'"), + sam->name, sam->loopstart, sam->start); + sam->loopstart = sam->start; + } -next_sample: - p = fluid_list_next (p); + if (invalid_loopend) + { + FLUID_LOG(FLUID_DBG, _("Sample '%s' has unusable loop stop '%d'," + " setting to sample stop at '%d'"), + sam->name, sam->loopend, sam->end); + /* since at this time sam->end points after valid sample data (will correct that few + * lines below), + * set loopend to that first invalid sample, since it should never be played, but + * instead the last + * valid sample will be played */ + sam->loopend = sam->end; + } + else if (loopend_end_mismatch) + { + FLUID_LOG(FLUID_DBG, _("Sample '%s' has invalid loop stop '%d'," + " sample stop at '%d', using it anyway"), + sam->name, sam->loopend, sam->end); + } + } + + /* convert sample end, loopstart, loopend to offsets from sam->start */ + sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */ + sam->loopstart -= sam->start; + sam->loopend -= sam->start; + + next_sample: + p = fluid_list_next(p); } - if(invalid_loops) + if (invalid_loops) { - FLUID_LOG (FLUID_WARN, _("Found samples with invalid loops, audible glitches possible.")); + FLUID_LOG(FLUID_WARN, _("Found samples with invalid loops, audible glitches possible.")); } - return (OK); + return (OK); } /* close SoundFont file and delete a SoundFont structure */ -void -sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs) +void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs) { - fluid_list_t *p, *p2; + fluid_list_t *p, *p2; - if (sf->sffd) - fcbs->fclose (sf->sffd); + if (sf->sffd) + fcbs->fclose(sf->sffd); - if (sf->fname) - free (sf->fname); + if (sf->fname) + free(sf->fname); - p = sf->info; - while (p) + p = sf->info; + while (p) { - free (p->data); - p = fluid_list_next (p); + free(p->data); + p = fluid_list_next(p); } - delete_fluid_list(sf->info); - sf->info = NULL; + delete_fluid_list(sf->info); + sf->info = NULL; - p = sf->preset; - while (p) - { /* loop over presets */ - p2 = ((SFPreset *) (p->data))->zone; - while (p2) - { /* loop over preset's zones */ - sfont_free_zone (p2->data); - p2 = fluid_list_next (p2); - } /* free preset's zone list */ - delete_fluid_list (((SFPreset *) (p->data))->zone); - FLUID_FREE (p->data); /* free preset chunk */ - p = fluid_list_next (p); + p = sf->preset; + while (p) + { /* loop over presets */ + p2 = ((SFPreset *)(p->data))->zone; + while (p2) + { /* loop over preset's zones */ + sfont_free_zone(p2->data); + p2 = fluid_list_next(p2); + } /* free preset's zone list */ + delete_fluid_list(((SFPreset *)(p->data))->zone); + FLUID_FREE(p->data); /* free preset chunk */ + p = fluid_list_next(p); } - delete_fluid_list (sf->preset); - sf->preset = NULL; + delete_fluid_list(sf->preset); + sf->preset = NULL; - p = sf->inst; - while (p) - { /* loop over instruments */ - p2 = ((SFInst *) (p->data))->zone; - while (p2) - { /* loop over inst's zones */ - sfont_free_zone (p2->data); - p2 = fluid_list_next (p2); - } /* free inst's zone list */ - delete_fluid_list (((SFInst *) (p->data))->zone); - FLUID_FREE (p->data); - p = fluid_list_next (p); + p = sf->inst; + while (p) + { /* loop over instruments */ + p2 = ((SFInst *)(p->data))->zone; + while (p2) + { /* loop over inst's zones */ + sfont_free_zone(p2->data); + p2 = fluid_list_next(p2); + } /* free inst's zone list */ + delete_fluid_list(((SFInst *)(p->data))->zone); + FLUID_FREE(p->data); + p = fluid_list_next(p); } - delete_fluid_list (sf->inst); - sf->inst = NULL; + delete_fluid_list(sf->inst); + sf->inst = NULL; - p = sf->sample; - while (p) + p = sf->sample; + while (p) { - FLUID_FREE (p->data); - p = fluid_list_next (p); + FLUID_FREE(p->data); + p = fluid_list_next(p); } - delete_fluid_list (sf->sample); - sf->sample = NULL; + delete_fluid_list(sf->sample); + sf->sample = NULL; - FLUID_FREE (sf); + FLUID_FREE(sf); } /* free all elements of a zone (Preset or Instrument) */ -void -sfont_free_zone (SFZone * zone) +void sfont_free_zone(SFZone *zone) { - fluid_list_t *p; + fluid_list_t *p; - if (!zone) - return; + if (!zone) + return; - p = zone->gen; - while (p) - { /* Free gen chunks for this zone */ - if (p->data) - FLUID_FREE (p->data); - p = fluid_list_next (p); + p = zone->gen; + while (p) + { /* Free gen chunks for this zone */ + if (p->data) + FLUID_FREE(p->data); + p = fluid_list_next(p); } - delete_fluid_list (zone->gen); /* free genlist */ + delete_fluid_list(zone->gen); /* free genlist */ - p = zone->mod; - while (p) - { /* Free mod chunks for this zone */ - if (p->data) - FLUID_FREE (p->data); - p = fluid_list_next (p); + p = zone->mod; + while (p) + { /* Free mod chunks for this zone */ + if (p->data) + FLUID_FREE(p->data); + p = fluid_list_next(p); } - delete_fluid_list (zone->mod); /* free modlist */ + delete_fluid_list(zone->mod); /* free modlist */ - FLUID_FREE (zone); /* free zone chunk */ + FLUID_FREE(zone); /* free zone chunk */ } /* preset sort function, first by bank, then by preset # */ -int -sfont_preset_compare_func (void* a, void* b) +int sfont_preset_compare_func(void *a, void *b) { - int aval, bval; + int aval, bval; - aval = (int) (((SFPreset *) a)->bank) << 16 | ((SFPreset *) a)->prenum; - bval = (int) (((SFPreset *) b)->bank) << 16 | ((SFPreset *) b)->prenum; + aval = (int)(((SFPreset *)a)->bank) << 16 | ((SFPreset *)a)->prenum; + bval = (int)(((SFPreset *)b)->bank) << 16 | ((SFPreset *)b)->prenum; - return (aval - bval); + return (aval - bval); } /* delete zone from zone list */ -void -sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone) +void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone) { - *zlist = fluid_list_remove (*zlist, (void*) zone); - sfont_free_zone (zone); + *zlist = fluid_list_remove(*zlist, (void *)zone); + sfont_free_zone(zone); } /* Find generator in gen list */ -fluid_list_t * -gen_inlist (int gen, fluid_list_t * genlist) -{ /* is generator in gen list? */ - fluid_list_t *p; +fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) +{ /* is generator in gen list? */ + fluid_list_t *p; - p = genlist; - while (p) + p = genlist; + while (p) { - if (p->data == NULL) - return (NULL); - if (gen == ((SFGen *) p->data)->id) - break; - p = fluid_list_next (p); + if (p->data == NULL) + return (NULL); + if (gen == ((SFGen *)p->data)->id) + break; + p = fluid_list_next(p); } - return (p); + return (p); } /* check validity of instrument generator */ -int -gen_valid (int gen) -{ /* is generator id valid? */ - int i = 0; +int gen_valid(int gen) +{ /* is generator id valid? */ + int i = 0; - if (gen > Gen_MaxValid) - return (FALSE); - while (badgen[i] && badgen[i] != gen) - i++; - return (badgen[i] == 0); + if (gen > Gen_MaxValid) + return (FALSE); + while (badgen[i] && badgen[i] != gen) + i++; + return (badgen[i] == 0); } /* check validity of preset generator */ -int -gen_validp (int gen) -{ /* is preset generator valid? */ - int i = 0; +int gen_validp(int gen) +{ /* is preset generator valid? */ + int i = 0; - if (!gen_valid (gen)) - return (FALSE); - while (badpgen[i] && badpgen[i] != (unsigned short) gen) - i++; - return (badpgen[i] == 0); + if (!gen_valid(gen)) + return (FALSE); + while (badpgen[i] && badpgen[i] != (unsigned short)gen) + i++; + return (badpgen[i] == 0); } /*================================util.c===========================*/ /* Logging function, returns FAIL to use as a return value in calling funcs */ -int -gerr (int ev, char * fmt, ...) +int gerr(int ev, char *fmt, ...) { - va_list args; + va_list args; - va_start (args, fmt); - vprintf(fmt, args); - va_end (args); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); - printf("\n"); + printf("\n"); - return (FAIL); + return (FAIL); } diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h index acee033e..21209312 100644 --- a/src/sfloader/fluid_sf2.h +++ b/src/sfloader/fluid_sf2.h @@ -35,118 +35,106 @@ /* Sound Font structure defines */ typedef struct _SFVersion -{ /* version structure */ - unsigned short major; - unsigned short minor; -} -SFVersion; +{ /* version structure */ + unsigned short major; + unsigned short minor; +} SFVersion; typedef struct _SFMod -{ /* Modulator structure */ - unsigned short src; /* source modulator */ - unsigned short dest; /* destination generator */ - signed short amount; /* signed, degree of modulation */ - unsigned short amtsrc; /* second source controls amnt of first */ - unsigned short trans; /* transform applied to source */ -} -SFMod; +{ /* Modulator structure */ + unsigned short src; /* source modulator */ + unsigned short dest; /* destination generator */ + signed short amount; /* signed, degree of modulation */ + unsigned short amtsrc; /* second source controls amnt of first */ + unsigned short trans; /* transform applied to source */ +} SFMod; -typedef union _SFGenAmount -{ /* Generator amount structure */ - signed short sword; /* signed 16 bit value */ - unsigned short uword; /* unsigned 16 bit value */ - struct - { - unsigned char lo; /* low value for ranges */ - unsigned char hi; /* high value for ranges */ - } - range; -} -SFGenAmount; +typedef union _SFGenAmount { /* Generator amount structure */ + signed short sword; /* signed 16 bit value */ + unsigned short uword; /* unsigned 16 bit value */ + struct + { + unsigned char lo; /* low value for ranges */ + unsigned char hi; /* high value for ranges */ + } range; +} SFGenAmount; typedef struct _SFGen -{ /* Generator structure */ - unsigned short id; /* generator ID */ - SFGenAmount amount; /* generator value */ -} -SFGen; +{ /* Generator structure */ + unsigned short id; /* generator ID */ + SFGenAmount amount; /* generator value */ +} SFGen; typedef struct _SFZone -{ /* Sample/instrument zone structure */ - fluid_list_t *instsamp; /* instrument/sample pointer for zone */ - fluid_list_t *gen; /* list of generators */ - fluid_list_t *mod; /* list of modulators */ -} -SFZone; +{ /* Sample/instrument zone structure */ + fluid_list_t *instsamp; /* instrument/sample pointer for zone */ + fluid_list_t *gen; /* list of generators */ + fluid_list_t *mod; /* list of modulators */ +} SFZone; typedef struct _SFSample -{ /* Sample structure */ - char name[21]; /* Name of sample */ - unsigned char samfile; /* Loaded sfont/sample buffer = 0/1 */ - unsigned int start; /* Offset in sample area to start of sample */ - unsigned int end; /* Offset from start to end of sample, - this is the last point of the - sample, the SF spec has this as the - 1st point after, corrected on - load/save */ - unsigned int loopstart; /* Offset from start to start of loop */ - unsigned int loopend; /* Offset from start to end of loop, - marks the first point after loop, - whose sample value is ideally - equivalent to loopstart */ - unsigned int samplerate; /* Sample rate recorded at */ - unsigned char origpitch; /* root midi key number */ - signed char pitchadj; /* pitch correction in cents */ - unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ - fluid_sample_t *fluid_sample; /* Imported sample (fixed up in fluid_defsfont_load) */ -} -SFSample; +{ /* Sample structure */ + char name[21]; /* Name of sample */ + unsigned char samfile; /* Loaded sfont/sample buffer = 0/1 */ + unsigned int start; /* Offset in sample area to start of sample */ + unsigned int end; /* Offset from start to end of sample, + this is the last point of the + sample, the SF spec has this as the + 1st point after, corrected on + load/save */ + unsigned int loopstart; /* Offset from start to start of loop */ + unsigned int loopend; /* Offset from start to end of loop, + marks the first point after loop, + whose sample value is ideally + equivalent to loopstart */ + unsigned int samplerate; /* Sample rate recorded at */ + unsigned char origpitch; /* root midi key number */ + signed char pitchadj; /* pitch correction in cents */ + unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ + fluid_sample_t *fluid_sample; /* Imported sample (fixed up in fluid_defsfont_load) */ +} SFSample; typedef struct _SFInst -{ /* Instrument structure */ - char name[21]; /* Name of instrument */ - fluid_list_t *zone; /* list of instrument zones */ -} -SFInst; +{ /* Instrument structure */ + char name[21]; /* Name of instrument */ + fluid_list_t *zone; /* list of instrument zones */ +} SFInst; typedef struct _SFPreset -{ /* Preset structure */ - char name[21]; /* preset name */ - unsigned short prenum; /* preset number */ - unsigned short bank; /* bank number */ - unsigned int libr; /* Not used (preserved) */ - unsigned int genre; /* Not used (preserved) */ - unsigned int morph; /* Not used (preserved) */ - fluid_list_t *zone; /* list of preset zones */ -} -SFPreset; +{ /* Preset structure */ + char name[21]; /* preset name */ + unsigned short prenum; /* preset number */ + unsigned short bank; /* bank number */ + unsigned int libr; /* Not used (preserved) */ + unsigned int genre; /* Not used (preserved) */ + unsigned int morph; /* Not used (preserved) */ + fluid_list_t *zone; /* list of preset zones */ +} SFPreset; /* NOTE: sffd is also used to determine if sound font is new (NULL) */ typedef struct _SFData -{ /* Sound font data structure */ - SFVersion version; /* sound font version */ - SFVersion romver; /* ROM version */ - - unsigned int samplepos; /* position within sffd of the sample chunk */ - unsigned int samplesize; /* length within sffd of the sample chunk */ - - unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */ - unsigned int sample24size; /* length within sffd of the sm24 chunk */ - - char *fname; /* file name */ - FILE *sffd; /* loaded sfont file descriptor */ - 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 */ - fluid_list_t *sample; /* linked list of sample info */ -} -SFData; +{ /* Sound font data structure */ + SFVersion version; /* sound font version */ + SFVersion romver; /* ROM version */ + + unsigned int samplepos; /* position within sffd of the sample chunk */ + unsigned int samplesize; /* length within sffd of the sample chunk */ + + unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit + sample support */ + unsigned int sample24size; /* length within sffd of the sm24 chunk */ + + char *fname; /* file name */ + FILE *sffd; /* loaded sfont file descriptor */ + 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 */ + fluid_list_t *sample; /* linked list of sample info */ +} SFData; /* functions */ - - /*-----------------------------------sffile.h----------------------------*/ /* File structures and routines (used to be in sffile.h) @@ -154,55 +142,50 @@ SFData; /* sfont file data structures */ typedef struct _SFChunk -{ /* RIFF file chunk structure */ - unsigned int id; /* chunk id */ - unsigned int size; /* size of the following chunk */ -} -SFChunk; +{ /* RIFF file chunk structure */ + unsigned int id; /* chunk id */ + unsigned int size; /* size of the following chunk */ +} SFChunk; typedef struct _SFPhdr { - unsigned char name[20]; /* preset name */ - unsigned short preset; /* preset number */ - unsigned short bank; /* bank number */ - unsigned short pbagndx; /* index into preset bag */ - unsigned int library; /* just for preserving them */ - unsigned int genre; /* Not used */ - unsigned int morphology; /* Not used */ -} -SFPhdr; + unsigned char name[20]; /* preset name */ + unsigned short preset; /* preset number */ + unsigned short bank; /* bank number */ + unsigned short pbagndx; /* index into preset bag */ + unsigned int library; /* just for preserving them */ + unsigned int genre; /* Not used */ + unsigned int morphology; /* Not used */ +} SFPhdr; typedef struct _SFBag { - unsigned short genndx; /* index into generator list */ - unsigned short modndx; /* index into modulator list */ -} -SFBag; + unsigned short genndx; /* index into generator list */ + unsigned short modndx; /* index into modulator list */ +} SFBag; typedef struct _SFIhdr { - char name[20]; /* Name of instrument */ - unsigned short ibagndx; /* Instrument bag index */ -} -SFIhdr; + char name[20]; /* Name of instrument */ + unsigned short ibagndx; /* Instrument bag index */ +} SFIhdr; typedef struct _SFShdr -{ /* Sample header loading struct */ - char name[20]; /* Sample name */ - unsigned int start; /* Offset to start of sample */ - unsigned int end; /* Offset to end of sample */ - unsigned int loopstart; /* Offset to start of loop */ - unsigned int loopend; /* Offset to end of loop */ - unsigned int samplerate; /* Sample rate recorded at */ - unsigned char origpitch; /* root midi key number */ - signed char pitchadj; /* pitch correction in cents */ - unsigned short samplelink; /* Not used */ - unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ -} -SFShdr; +{ /* Sample header loading struct */ + char name[20]; /* Sample name */ + unsigned int start; /* Offset to start of sample */ + unsigned int end; /* Offset to end of sample */ + unsigned int loopstart; /* Offset to start of loop */ + unsigned int loopend; /* Offset to end of loop */ + unsigned int samplerate; /* Sample rate recorded at */ + unsigned char origpitch; /* root midi key number */ + signed char pitchadj; /* pitch correction in cents */ + unsigned short samplelink; /* Not used */ + unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ +} SFShdr; /* Public functions */ -SFData *sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs); -void sfont_close (SFData * sf, const fluid_file_callbacks_t* fcbs); +SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs); +void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs); -#endif /* _FLUID_SF2_H */ +#endif /* _FLUID_SF2_H */ From d538d7f52c54906ebbde22b3b0d848f3312784af Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 07/47] Cleanup error handling, remove gerr function --- src/sfloader/fluid_sf2.c | 270 ++++++++++++++++++++++++++++----------- 1 file changed, 192 insertions(+), 78 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 26b422f8..52b72145 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -164,14 +164,6 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, #define FAIL 0 #define OK 1 -enum -{ - ErrCorr, -}; - -int gerr(int ev, char *fmt, ...); - - #define CHNKIDSTR(id) &idlist[(id - 1) * 4] /* sfont file chunk sizes */ @@ -376,7 +368,7 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (chunk.size != size - 8) { - gerr(ErrCorr, _("SoundFont file size mismatch")); + FLUID_LOG(FLUID_ERR, _("SoundFont file size mismatch")); return (FAIL); } @@ -384,7 +376,10 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (!read_listchunk(&chunk, fd, fcbs)) return (FAIL); if (chunkid(chunk.id) != INFO_ID) - return (gerr(ErrCorr, _("Invalid ID found when expecting INFO chunk"))); + { + FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting INFO chunk")); + return (FAIL); + } if (!process_info(chunk.size, sf, fd, fcbs)) return (FAIL); @@ -392,7 +387,10 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (!read_listchunk(&chunk, fd, fcbs)) return (FAIL); if (chunkid(chunk.id) != SDTA_ID) - return (gerr(ErrCorr, _("Invalid ID found when expecting SAMPLE chunk"))); + { + FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting SAMPLE chunk")); + return (FAIL); + } if (!process_sdta(chunk.size, sf, fd, fcbs)) return (FAIL); @@ -400,7 +398,10 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (!read_listchunk(&chunk, fd, fcbs)) return (FAIL); if (chunkid(chunk.id) != PDTA_ID) - return (gerr(ErrCorr, _("Invalid ID found when expecting HYDRA chunk"))); + { + FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting HYDRA chunk")); + return (FAIL); + } if (!process_pdta(chunk.size, sf, fd, fcbs)) return (FAIL); @@ -421,7 +422,10 @@ static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t { READCHUNK(chunk, fd, fcbs); /* read list chunk */ if (chunkid(chunk->id) != LIST_ID) /* error if ! list chunk */ - return (gerr(ErrCorr, _("Invalid chunk id in level 0 parse"))); + { + FLUID_LOG(FLUID_ERR, _("Invalid chunk id in level 0 parse")); + return (FAIL); + } READID(&chunk->id, fd, fcbs); /* read id string */ chunk->size -= 4; return (OK); @@ -444,7 +448,10 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac if (id == IFIL_ID) { /* sound font version chunk? */ if (chunk.size != 4) - return (gerr(ErrCorr, _("Sound font version info chunk has invalid size"))); + { + FLUID_LOG(FLUID_ERR, _("Sound font version info chunk has invalid size")); + return (FAIL); + } READW(ver, fd, fcbs); sf->version.major = ver; @@ -481,7 +488,10 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac else if (id == IVER_ID) { /* ROM version chunk? */ if (chunk.size != 4) - return (gerr(ErrCorr, _("ROM version info chunk has invalid size"))); + { + FLUID_LOG(FLUID_ERR, _("ROM version info chunk has invalid size")); + return (FAIL); + } READW(ver, fd, fcbs); sf->romver.major = ver; @@ -491,9 +501,11 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac else if (id != UNKN_ID) { if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) || (chunk.size % 2)) - return (gerr(ErrCorr, _("INFO sub chunk %.4s has invalid chunk size" - " of %d bytes"), - &chunk.id, chunk.size)); + { + FLUID_LOG(FLUID_ERR, _("INFO sub chunk %.4s has invalid chunk size of %d bytes"), + &chunk.id, chunk.size); + return (FAIL); + } /* alloc for chunk id and da chunk */ if (!(item = FLUID_MALLOC(chunk.size + 1))) @@ -513,12 +525,18 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac *(item + chunk.size) = '\0'; } else - return (gerr(ErrCorr, _("Invalid chunk id in INFO chunk"))); + { + FLUID_LOG(FLUID_ERR, _("Invalid chunk id in INFO chunk")); + return (FAIL); + } size -= chunk.size; } if (size < 0) - return (gerr(ErrCorr, _("INFO chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("INFO chunk size mismatch")); + return (FAIL); + } return (OK); } @@ -535,13 +553,19 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil size -= 8; if (chunkid(chunk.id) != SMPL_ID) - return (gerr(ErrCorr, _("Expected SMPL chunk found invalid id instead"))); + { + FLUID_LOG(FLUID_ERR, _("Expected SMPL chunk found invalid id instead")); + return (FAIL); + } /* SDTA chunk may also contain sm24 chunk for 24 bit samples * (not yet supported), only an error if SMPL chunk size is * greater than SDTA. */ if (chunk.size > size) - return (gerr(ErrCorr, _("SDTA chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("SDTA chunk size mismatch")); + return (FAIL); + } /* sample data follows */ sf->samplepos = fcbs->ftell(fd); @@ -609,14 +633,21 @@ static int pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, i *size -= 8; if ((id = chunkid(chunk->id)) != expid) - return (gerr(ErrCorr, _("Expected" - " PDTA sub-chunk \"%.4s\" found invalid id instead"), - expstr)); + { + FLUID_LOG(FLUID_ERR, _("Expected PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr); + return (FAIL); + } if (chunk->size % reclen) /* valid chunk size? */ - return (gerr(ErrCorr, _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, reclen)); + { + FLUID_LOG(FLUID_ERR, _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, reclen); + return (FAIL); + } if ((*size -= chunk->size) < 0) - return (gerr(ErrCorr, _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr)); + { + FLUID_LOG(FLUID_ERR, _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr); + return (FAIL); + } return (OK); } @@ -680,7 +711,10 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ unsigned short zndx, pzndx = 0; if (size % SFPHDRSIZE || size == 0) - return (gerr(ErrCorr, _("Preset header chunk size is invalid"))); + { + FLUID_LOG(FLUID_ERR, _("Preset header chunk size is invalid")); + return (FAIL); + } i = size / SFPHDRSIZE - 1; if (i == 0) @@ -706,7 +740,10 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (pr) { /* not first preset? */ if (zndx < pzndx) - return (gerr(ErrCorr, _("Preset header indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); + return (FAIL); + } i2 = zndx - pzndx; while (i2--) { @@ -724,7 +761,10 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FSKIP(12, fd, fcbs); if (zndx < pzndx) - return (gerr(ErrCorr, _("Preset header indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); + return (FAIL); + } i2 = zndx - pzndx; while (i2--) { @@ -744,7 +784,10 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ unsigned short i; if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr(ErrCorr, _("Preset bag chunk size is invalid"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag chunk size is invalid")); + return (FAIL); + } p = sf->preset; while (p) @@ -753,7 +796,10 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ while (p2) { /* traverse preset's zones */ if ((size -= SFBAGSIZE) < 0) - return (gerr(ErrCorr, _("Preset bag chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); + return (FAIL); + } z = FLUID_NEW(SFZone); p2->data = z; z->gen = NULL; /* Init gen and mod before possible failure, */ @@ -765,9 +811,15 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (pz) { /* if not first zone */ if (genndx < pgenndx) - return (gerr(ErrCorr, _("Preset bag generator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag generator indices not monotonic")); + return (FAIL); + } if (modndx < pmodndx) - return (gerr(ErrCorr, _("Preset bag modulator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag modulator indices not monotonic")); + return (FAIL); + } i = genndx - pgenndx; while (i--) pz->gen = fluid_list_prepend(pz->gen, NULL); @@ -785,7 +837,10 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ size -= SFBAGSIZE; if (size != 0) - return (gerr(ErrCorr, _("Preset bag chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); + return (FAIL); + } READW(genndx, fd, fcbs); READW(modndx, fd, fcbs); @@ -800,9 +855,15 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } if (genndx < pgenndx) - return (gerr(ErrCorr, _("Preset bag generator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag generator indices not monotonic")); + return (FAIL); + } if (modndx < pmodndx) - return (gerr(ErrCorr, _("Preset bag modulator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Preset bag modulator indices not monotonic")); + return (FAIL); + } i = genndx - pgenndx; while (i--) pz->gen = fluid_list_prepend(pz->gen, NULL); @@ -829,7 +890,10 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ while (p3) { /* load zone's modulators */ if ((size -= SFMODSIZE) < 0) - return (gerr(ErrCorr, _("Preset modulator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); + return (FAIL); + } m = FLUID_NEW(SFMod); p3->data = m; READW(m->src, fd, fcbs); @@ -853,7 +917,10 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ size -= SFMODSIZE; if (size != 0) - return (gerr(ErrCorr, _("Preset modulator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); + return (FAIL); + } FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ return (OK); @@ -899,7 +966,10 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ skip = FALSE; drop = FALSE; if ((size -= SFGENSIZE) < 0) - return (gerr(ErrCorr, _("Preset generator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); + return (FAIL); + } READW(genid, fd, fcbs); @@ -1004,7 +1074,10 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* Kill any zones following an instrument */ discarded = TRUE; if ((size -= SFGENSIZE) < 0) - return (gerr(ErrCorr, _("Preset generator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); + return (FAIL); + } FSKIP(SFGENSIZE, fd, fcbs); SLADVREM(z->gen, p3); } @@ -1023,7 +1096,10 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ size -= SFGENSIZE; if (size != 0) - return (gerr(ErrCorr, _("Preset generator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); + return (FAIL); + } FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ return (OK); @@ -1037,7 +1113,10 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ unsigned short zndx, pzndx = 0; if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ - return (gerr(ErrCorr, _("Instrument header has invalid size"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument header has invalid size")); + return (FAIL); + } size = size / SFIHDRSIZE - 1; if (size == 0) @@ -1058,7 +1137,10 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (pr) { /* not first instrument? */ if (zndx < pzndx) - return (gerr(ErrCorr, _("Instrument header indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument header indices not monotonic")); + return (FAIL); + } i2 = zndx - pzndx; while (i2--) pr->zone = fluid_list_prepend(pr->zone, NULL); @@ -1073,7 +1155,10 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ READW(zndx, fd, fcbs); if (zndx < pzndx) - return (gerr(ErrCorr, _("Instrument header indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument header indices not monotonic")); + return (FAIL); + } i2 = zndx - pzndx; while (i2--) pr->zone = fluid_list_prepend(pr->zone, NULL); @@ -1090,7 +1175,10 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ int i; if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ - return (gerr(ErrCorr, _("Instrument bag chunk size is invalid"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size is invalid")); + return (FAIL); + } p = sf->inst; while (p) @@ -1099,7 +1187,10 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ while (p2) { /* load this inst's zones */ if ((size -= SFBAGSIZE) < 0) - return (gerr(ErrCorr, _("Instrument bag chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size mismatch")); + return (FAIL); + } z = FLUID_NEW(SFZone); p2->data = z; z->gen = NULL; /* In case of failure, */ @@ -1111,9 +1202,15 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (pz) { /* if not first zone */ if (genndx < pgenndx) - return (gerr(ErrCorr, _("Instrument generator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument generator indices not monotonic")); + return (FAIL); + } if (modndx < pmodndx) - return (gerr(ErrCorr, _("Instrument modulator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument modulator indices not monotonic")); + return (FAIL); + } i = genndx - pgenndx; while (i--) pz->gen = fluid_list_prepend(pz->gen, NULL); @@ -1131,7 +1228,10 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ size -= SFBAGSIZE; if (size != 0) - return (gerr(ErrCorr, _("Instrument chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument chunk size mismatch")); + return (FAIL); + } READW(genndx, fd, fcbs); READW(modndx, fd, fcbs); @@ -1146,9 +1246,15 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } if (genndx < pgenndx) - return (gerr(ErrCorr, _("Instrument generator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument generator indices not monotonic")); + return (FAIL); + } if (modndx < pmodndx) - return (gerr(ErrCorr, _("Instrument modulator indices not monotonic"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument modulator indices not monotonic")); + return (FAIL); + } i = genndx - pgenndx; while (i--) pz->gen = fluid_list_prepend(pz->gen, NULL); @@ -1175,7 +1281,10 @@ static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ while (p3) { /* load zone's modulators */ if ((size -= SFMODSIZE) < 0) - return (gerr(ErrCorr, _("Instrument modulator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); + return (FAIL); + } m = FLUID_NEW(SFMod); p3->data = m; READW(m->src, fd, fcbs); @@ -1199,7 +1308,10 @@ static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ size -= SFMODSIZE; if (size != 0) - return (gerr(ErrCorr, _("Instrument modulator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); + return (FAIL); + } FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ return (OK); @@ -1234,7 +1346,10 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ skip = FALSE; drop = FALSE; if ((size -= SFGENSIZE) < 0) - return (gerr(ErrCorr, _("IGEN chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); + return (FAIL); + } READW(genid, fd, fcbs); @@ -1339,7 +1454,10 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* Kill any zones following a sample */ discarded = TRUE; if ((size -= SFGENSIZE) < 0) - return (gerr(ErrCorr, _("Instrument generator chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("Instrument generator chunk size mismatch")); + return (FAIL); + } FSKIP(SFGENSIZE, fd, fcbs); SLADVREM(z->gen, p3); } @@ -1358,7 +1476,10 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ size -= SFGENSIZE; if (size != 0) - return (gerr(ErrCorr, _("IGEN chunk size mismatch"))); + { + FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); + return (FAIL); + } FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ return (OK); @@ -1371,7 +1492,10 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c SFSample *p; if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ - return (gerr(ErrCorr, _("Sample header has invalid size"))); + { + FLUID_LOG(FLUID_ERR, _("Sample header has invalid size")); + return (FAIL); + } size = size / SFSHDRSIZE - 1; if (size == 0) @@ -1422,8 +1546,11 @@ static int fixup_pgen(SFData *sf) { /* load instrument # */ p3 = fluid_list_nth(sf->inst, i - 1); if (!p3) - return (gerr(ErrCorr, _("Preset %03d %03d: Invalid instrument reference"), - ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum)); + { + FLUID_LOG(FLUID_ERR, _("Preset %03d %03d: Invalid instrument reference"), + ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum); + return (FAIL); + } z->instsamp = p3; } else @@ -1454,8 +1581,11 @@ static int fixup_igen(SFData *sf) { /* load sample # */ p3 = fluid_list_nth(sf->sample, i - 1); if (!p3) - return (gerr(ErrCorr, _("Instrument \"%s\": Invalid sample reference"), - ((SFInst *)(p->data))->name)); + { + FLUID_LOG(FLUID_ERR, _("Instrument \"%s\": Invalid sample reference"), + ((SFInst *)(p->data))->name); + return (FAIL); + } z->instsamp = p3; } p2 = fluid_list_next(p2); @@ -1735,19 +1865,3 @@ int gen_validp(int gen) i++; return (badpgen[i] == 0); } - -/*================================util.c===========================*/ - -/* Logging function, returns FAIL to use as a return value in calling funcs */ -int gerr(int ev, char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - - printf("\n"); - - return (FAIL); -} From 4dbc31215feb998299e0b7e3adca0e5b6639b27b Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 08/47] Make all private functions static --- src/sfloader/fluid_sf2.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 52b72145..bfb89216 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -267,14 +267,12 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c static int fixup_pgen(SFData *sf); static int fixup_igen(SFData *sf); static int fixup_sample(SFData *sf); - - -void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone); -int sfont_preset_compare_func(void *a, void *b); -void sfont_free_zone(SFZone *zone); -fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist); -int gen_valid(int gen); -int gen_validp(int gen); +static void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone); +static void sfont_free_zone(SFZone *zone); +static int sfont_preset_compare_func(void *a, void *b); +static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist); +static int gen_valid(int gen); +static int gen_validp(int gen); static const char idlist[] = {"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" @@ -1779,7 +1777,7 @@ void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs) } /* free all elements of a zone (Preset or Instrument) */ -void sfont_free_zone(SFZone *zone) +static void sfont_free_zone(SFZone *zone) { fluid_list_t *p; @@ -1808,7 +1806,7 @@ void sfont_free_zone(SFZone *zone) } /* preset sort function, first by bank, then by preset # */ -int sfont_preset_compare_func(void *a, void *b) +static int sfont_preset_compare_func(void *a, void *b) { int aval, bval; @@ -1819,14 +1817,14 @@ int sfont_preset_compare_func(void *a, void *b) } /* delete zone from zone list */ -void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone) +static void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone) { *zlist = fluid_list_remove(*zlist, (void *)zone); sfont_free_zone(zone); } /* Find generator in gen list */ -fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) +static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) { /* is generator in gen list? */ fluid_list_t *p; @@ -1843,7 +1841,7 @@ fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) } /* check validity of instrument generator */ -int gen_valid(int gen) +static int gen_valid(int gen) { /* is generator id valid? */ int i = 0; @@ -1855,7 +1853,7 @@ int gen_valid(int gen) } /* check validity of preset generator */ -int gen_validp(int gen) +static int gen_validp(int gen) { /* is preset generator valid? */ int i = 0; From f83c49d6fa7f1ec4818cb9e920e30adc827d28bf Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 09/47] Remove sfont_zone_delete, replace with direct invocations instead --- src/sfloader/fluid_sf2.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index bfb89216..9e5157c6 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -267,7 +267,6 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c static int fixup_pgen(SFData *sf); static int fixup_igen(SFData *sf); static int fixup_sample(SFData *sf); -static void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone); static void sfont_free_zone(SFZone *zone); static int sfont_preset_compare_func(void *a, void *b); static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist); @@ -1064,7 +1063,8 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* previous global zone exists, discard */ FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Discarding invalid global zone"), ((SFPreset *)(p->data))->name); - sfont_zone_delete(sf, hz, (SFZone *)(p2->data)); + *hz = fluid_list_remove(*hz, p2->data); + sfont_free_zone((SFZone *)fluid_list_get(p2)); } } @@ -1444,7 +1444,8 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* previous global zone exists, discard */ FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Discarding invalid global zone"), ((SFInst *)(p->data))->name); - sfont_zone_delete(sf, hz, (SFZone *)(p2->data)); + *hz = fluid_list_remove(*hz, p2->data); + sfont_free_zone((SFZone *)fluid_list_get(p2)); } } @@ -1816,13 +1817,6 @@ static int sfont_preset_compare_func(void *a, void *b) return (aval - bval); } -/* delete zone from zone list */ -static void sfont_zone_delete(SFData *sf, fluid_list_t **zlist, SFZone *zone) -{ - *zlist = fluid_list_remove(*zlist, (void *)zone); - sfont_free_zone(zone); -} - /* Find generator in gen list */ static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) { /* is generator in gen list? */ From af3e6bba01f036d6f5f2f1265d72edfe5a6fde18 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 10/47] Cleanup return values --- src/sfloader/fluid_sf2.c | 255 +++++++++++++++++++-------------------- 1 file changed, 126 insertions(+), 129 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 9e5157c6..cbfb2dca 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -161,9 +161,6 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, 0}; -#define FAIL 0 -#define OK 1 - #define CHNKIDSTR(id) &idlist[(id - 1) * 4] /* sfont file chunk sizes */ @@ -179,7 +176,7 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, do \ { \ if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \ } while (0) @@ -188,7 +185,7 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, { \ uint32_t _temp; \ if (fcbs->fread(&_temp, 4, fd) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ var = FLUID_LE32TOH(_temp); \ } while (0) @@ -197,7 +194,7 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, { \ uint16_t _temp; \ if (fcbs->fread(&_temp, 2, fd) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ var = FLUID_LE16TOH(_temp); \ } while (0) @@ -205,14 +202,14 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, do \ { \ if (fcbs->fread(var, 4, fd) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ } while (0) #define READSTR(var, fd, fcbs) \ do \ { \ if (fcbs->fread(var, 20, fd) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ (*var)[20] = '\0'; \ } while (0) @@ -220,21 +217,21 @@ static const unsigned short badpgen[] = {Gen_StartAddrOfs, do \ { \ if (fcbs->fread(&var, 1, fd) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ } while (0) #define FSKIP(size, fd, fcbs) \ do \ { \ if (fcbs->fseek(fd, size, SEEK_CUR) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ } while (0) #define FSKIPW(fd, fcbs) \ do \ { \ if (fcbs->fseek(fd, 2, SEEK_CUR) == FLUID_FAILED) \ - return (FAIL); \ + return FALSE; \ } while (0) /* removes and advances a fluid_list_t pointer */ @@ -288,7 +285,7 @@ static int chunkid(unsigned int id) if (*p == id) return (i + 1); - return (UNKN_ID); + return UNKN_ID; } SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs) @@ -301,7 +298,7 @@ SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs) if ((fd = fcbs->fopen(fname)) == NULL) { FLUID_LOG(FLUID_ERR, _("Unable to open file \"%s\""), fname); - return (NULL); + return NULL; } if (!(sf = FLUID_NEW(SFData))) @@ -339,10 +336,10 @@ SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs) { if (sf) sfont_close(sf, fcbs); - return (NULL); + return NULL; } - return (sf); + return sf; } static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) @@ -353,66 +350,66 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (chunkid(chunk.id) != RIFF_ID) { /* error if not RIFF */ FLUID_LOG(FLUID_ERR, _("Not a RIFF file")); - return (FAIL); + return FALSE; } READID(&chunk.id, fd, fcbs); /* load file ID */ if (chunkid(chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ FLUID_LOG(FLUID_ERR, _("Not a SoundFont file")); - return (FAIL); + return FALSE; } if (chunk.size != size - 8) { FLUID_LOG(FLUID_ERR, _("SoundFont file size mismatch")); - return (FAIL); + return FALSE; } /* Process INFO block */ if (!read_listchunk(&chunk, fd, fcbs)) - return (FAIL); + return FALSE; if (chunkid(chunk.id) != INFO_ID) { FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting INFO chunk")); - return (FAIL); + return FALSE; } if (!process_info(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; /* Process sample chunk */ if (!read_listchunk(&chunk, fd, fcbs)) - return (FAIL); + return FALSE; if (chunkid(chunk.id) != SDTA_ID) { FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting SAMPLE chunk")); - return (FAIL); + return FALSE; } if (!process_sdta(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; /* process HYDRA chunk */ if (!read_listchunk(&chunk, fd, fcbs)) - return (FAIL); + return FALSE; if (chunkid(chunk.id) != PDTA_ID) { FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting HYDRA chunk")); - return (FAIL); + return FALSE; } if (!process_pdta(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!fixup_pgen(sf)) - return (FAIL); + return FALSE; if (!fixup_igen(sf)) - return (FAIL); + return FALSE; if (!fixup_sample(sf)) - return (FAIL); + return FALSE; /* sort preset list by bank, preset # */ sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)sfont_preset_compare_func); - return (OK); + return TRUE; } static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t *fcbs) @@ -421,11 +418,11 @@ static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t if (chunkid(chunk->id) != LIST_ID) /* error if ! list chunk */ { FLUID_LOG(FLUID_ERR, _("Invalid chunk id in level 0 parse")); - return (FAIL); + return FALSE; } READID(&chunk->id, fd, fcbs); /* read id string */ chunk->size -= 4; - return (OK); + return TRUE; } static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) @@ -447,7 +444,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac if (chunk.size != 4) { FLUID_LOG(FLUID_ERR, _("Sound font version info chunk has invalid size")); - return (FAIL); + return FALSE; } READW(ver, fd, fcbs); @@ -460,7 +457,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac FLUID_LOG(FLUID_ERR, _("Sound font version is %d.%d which is not" " supported, convert to version 2.0x"), sf->version.major, sf->version.minor); - return (FAIL); + return FALSE; } if (sf->version.major == 3) @@ -470,7 +467,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac _("Sound font version is %d.%d but fluidsynth was compiled without" " support for (v3.x)"), sf->version.major, sf->version.minor); - return (FAIL); + return FALSE; #endif } else if (sf->version.major > 2) @@ -479,7 +476,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac _("Sound font version is %d.%d which is newer than" " what this version of fluidsynth was designed for (v2.0x)"), sf->version.major, sf->version.minor); - return (FAIL); + return FALSE; } } else if (id == IVER_ID) @@ -487,7 +484,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac if (chunk.size != 4) { FLUID_LOG(FLUID_ERR, _("ROM version info chunk has invalid size")); - return (FAIL); + return FALSE; } READW(ver, fd, fcbs); @@ -501,14 +498,14 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac { FLUID_LOG(FLUID_ERR, _("INFO sub chunk %.4s has invalid chunk size of %d bytes"), &chunk.id, chunk.size); - return (FAIL); + return FALSE; } /* alloc for chunk id and da chunk */ if (!(item = FLUID_MALLOC(chunk.size + 1))) { FLUID_LOG(FLUID_ERR, "Out of memory"); - return (FAIL); + return FALSE; } /* attach to INFO list, sfont_close will cleanup if FAIL occurs */ @@ -516,7 +513,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac *(unsigned char *)item = id; if (fcbs->fread(&item[1], chunk.size, fd) == FLUID_FAILED) - return (FAIL); + return FALSE; /* force terminate info item (don't forget uint8 info ID) */ *(item + chunk.size) = '\0'; @@ -524,7 +521,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac else { FLUID_LOG(FLUID_ERR, _("Invalid chunk id in INFO chunk")); - return (FAIL); + return FALSE; } size -= chunk.size; } @@ -532,10 +529,10 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac if (size < 0) { FLUID_LOG(FLUID_ERR, _("INFO chunk size mismatch")); - return (FAIL); + return FALSE; } - return (OK); + return TRUE; } static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) @@ -543,7 +540,7 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil SFChunk chunk; if (size == 0) - return (OK); /* no sample data? */ + return TRUE; /* no sample data? */ /* read sub chunk */ READCHUNK(&chunk, fd, fcbs); @@ -552,7 +549,7 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil if (chunkid(chunk.id) != SMPL_ID) { FLUID_LOG(FLUID_ERR, _("Expected SMPL chunk found invalid id instead")); - return (FAIL); + return FALSE; } /* SDTA chunk may also contain sm24 chunk for 24 bit samples @@ -561,7 +558,7 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil if (chunk.size > size) { FLUID_LOG(FLUID_ERR, _("SDTA chunk size mismatch")); - return (FAIL); + return FALSE; } /* sample data follows */ @@ -616,7 +613,7 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil ret: FSKIP(size, fd, fcbs); - return (OK); + return TRUE; } static int pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size, void *fd, const fluid_file_callbacks_t *fcbs) @@ -632,20 +629,20 @@ static int pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, i if ((id = chunkid(chunk->id)) != expid) { FLUID_LOG(FLUID_ERR, _("Expected PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr); - return (FAIL); + return FALSE; } if (chunk->size % reclen) /* valid chunk size? */ { FLUID_LOG(FLUID_ERR, _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, reclen); - return (FAIL); + return FALSE; } if ((*size -= chunk->size) < 0) { FLUID_LOG(FLUID_ERR, _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr); - return (FAIL); + return FALSE; } - return (OK); + return TRUE; } static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) @@ -653,51 +650,51 @@ static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbac SFChunk chunk; if (!pdtahelper(PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_phdr(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_pbag(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_pmod(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_pgen(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_ihdr(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_ibag(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_imod(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_igen(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; if (!pdtahelper(SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs)) - return (FAIL); + return FALSE; if (!load_shdr(chunk.size, sf, fd, fcbs)) - return (FAIL); + return FALSE; - return (OK); + return TRUE; } /* preset header loader */ @@ -710,7 +707,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size % SFPHDRSIZE || size == 0) { FLUID_LOG(FLUID_ERR, _("Preset header chunk size is invalid")); - return (FAIL); + return FALSE; } i = size / SFPHDRSIZE - 1; @@ -718,7 +715,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* at least one preset + term record */ FLUID_LOG(FLUID_WARN, _("File contains no presets")); FSKIP(SFPHDRSIZE, fd, fcbs); - return (OK); + return TRUE; } for (; i > 0; i--) @@ -739,7 +736,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (zndx < pzndx) { FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); - return (FAIL); + return FALSE; } i2 = zndx - pzndx; while (i2--) @@ -760,7 +757,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (zndx < pzndx) { FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); - return (FAIL); + return FALSE; } i2 = zndx - pzndx; while (i2--) @@ -768,7 +765,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ pr->zone = fluid_list_prepend(pr->zone, NULL); } - return (OK); + return TRUE; } /* preset bag loader */ @@ -783,7 +780,7 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ { FLUID_LOG(FLUID_ERR, _("Preset bag chunk size is invalid")); - return (FAIL); + return FALSE; } p = sf->preset; @@ -795,7 +792,7 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFBAGSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); - return (FAIL); + return FALSE; } z = FLUID_NEW(SFZone); p2->data = z; @@ -810,12 +807,12 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (genndx < pgenndx) { FLUID_LOG(FLUID_ERR, _("Preset bag generator indices not monotonic")); - return (FAIL); + return FALSE; } if (modndx < pmodndx) { FLUID_LOG(FLUID_ERR, _("Preset bag modulator indices not monotonic")); - return (FAIL); + return FALSE; } i = genndx - pgenndx; while (i--) @@ -836,7 +833,7 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size != 0) { FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); - return (FAIL); + return FALSE; } READW(genndx, fd, fcbs); @@ -848,18 +845,18 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_WARN, _("No preset generators and terminal index not 0")); if (modndx > 0) FLUID_LOG(FLUID_WARN, _("No preset modulators and terminal index not 0")); - return (OK); + return TRUE; } if (genndx < pgenndx) { FLUID_LOG(FLUID_ERR, _("Preset bag generator indices not monotonic")); - return (FAIL); + return FALSE; } if (modndx < pmodndx) { FLUID_LOG(FLUID_ERR, _("Preset bag modulator indices not monotonic")); - return (FAIL); + return FALSE; } i = genndx - pgenndx; while (i--) @@ -868,7 +865,7 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ while (i--) pz->mod = fluid_list_prepend(pz->mod, NULL); - return (OK); + return TRUE; } /* preset modulator loader */ @@ -889,7 +886,7 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFMODSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); - return (FAIL); + return FALSE; } m = FLUID_NEW(SFMod); p3->data = m; @@ -910,17 +907,17 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ Hmmm, the specs say there should be one, but.. */ if (size == 0) - return (OK); + return TRUE; size -= SFMODSIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); - return (FAIL); + return FALSE; } FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ - return (OK); + return TRUE; } /* ------------------------------------------------------------------- @@ -965,7 +962,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFGENSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); - return (FAIL); + return FALSE; } READW(genid, fd, fcbs); @@ -1074,7 +1071,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFGENSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); - return (FAIL); + return FALSE; } FSKIP(SFGENSIZE, fd, fcbs); SLADVREM(z->gen, p3); @@ -1090,17 +1087,17 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ /* in case there isn't a terminal record */ if (size == 0) - return (OK); + return TRUE; size -= SFGENSIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); - return (FAIL); + return FALSE; } FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ - return (OK); + return TRUE; } /* instrument header loader */ @@ -1113,7 +1110,7 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ { FLUID_LOG(FLUID_ERR, _("Instrument header has invalid size")); - return (FAIL); + return FALSE; } size = size / SFIHDRSIZE - 1; @@ -1121,7 +1118,7 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* at least one preset + term record */ FLUID_LOG(FLUID_WARN, _("File contains no instruments")); FSKIP(SFIHDRSIZE, fd, fcbs); - return (OK); + return TRUE; } for (i = 0; i < size; i++) @@ -1137,7 +1134,7 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (zndx < pzndx) { FLUID_LOG(FLUID_ERR, _("Instrument header indices not monotonic")); - return (FAIL); + return FALSE; } i2 = zndx - pzndx; while (i2--) @@ -1155,13 +1152,13 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (zndx < pzndx) { FLUID_LOG(FLUID_ERR, _("Instrument header indices not monotonic")); - return (FAIL); + return FALSE; } i2 = zndx - pzndx; while (i2--) pr->zone = fluid_list_prepend(pr->zone, NULL); - return (OK); + return TRUE; } /* instrument bag loader */ @@ -1175,7 +1172,7 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ { FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size is invalid")); - return (FAIL); + return FALSE; } p = sf->inst; @@ -1187,7 +1184,7 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFBAGSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size mismatch")); - return (FAIL); + return FALSE; } z = FLUID_NEW(SFZone); p2->data = z; @@ -1202,12 +1199,12 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (genndx < pgenndx) { FLUID_LOG(FLUID_ERR, _("Instrument generator indices not monotonic")); - return (FAIL); + return FALSE; } if (modndx < pmodndx) { FLUID_LOG(FLUID_ERR, _("Instrument modulator indices not monotonic")); - return (FAIL); + return FALSE; } i = genndx - pgenndx; while (i--) @@ -1228,7 +1225,7 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size != 0) { FLUID_LOG(FLUID_ERR, _("Instrument chunk size mismatch")); - return (FAIL); + return FALSE; } READW(genndx, fd, fcbs); @@ -1240,18 +1237,18 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_WARN, _("No instrument generators and terminal index not 0")); if (modndx > 0) FLUID_LOG(FLUID_WARN, _("No instrument modulators and terminal index not 0")); - return (OK); + return TRUE; } if (genndx < pgenndx) { FLUID_LOG(FLUID_ERR, _("Instrument generator indices not monotonic")); - return (FAIL); + return FALSE; } if (modndx < pmodndx) { FLUID_LOG(FLUID_ERR, _("Instrument modulator indices not monotonic")); - return (FAIL); + return FALSE; } i = genndx - pgenndx; while (i--) @@ -1260,7 +1257,7 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ while (i--) pz->mod = fluid_list_prepend(pz->mod, NULL); - return (OK); + return TRUE; } /* instrument modulator loader */ @@ -1281,7 +1278,7 @@ static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFMODSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); - return (FAIL); + return FALSE; } m = FLUID_NEW(SFMod); p3->data = m; @@ -1302,17 +1299,17 @@ static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ Hmmm, the specs say there should be one, but.. */ if (size == 0) - return (OK); + return TRUE; size -= SFMODSIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); - return (FAIL); + return FALSE; } FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ - return (OK); + return TRUE; } /* load instrument generators (see load_pgen for loading rules) */ @@ -1346,7 +1343,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFGENSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); - return (FAIL); + return FALSE; } READW(genid, fd, fcbs); @@ -1455,7 +1452,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if ((size -= SFGENSIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Instrument generator chunk size mismatch")); - return (FAIL); + return FALSE; } FSKIP(SFGENSIZE, fd, fcbs); SLADVREM(z->gen, p3); @@ -1471,17 +1468,17 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ /* for those non-terminal record cases, grr! */ if (size == 0) - return (OK); + return TRUE; size -= SFGENSIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); - return (FAIL); + return FALSE; } FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ - return (OK); + return TRUE; } /* sample header loader */ @@ -1493,7 +1490,7 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ { FLUID_LOG(FLUID_ERR, _("Sample header has invalid size")); - return (FAIL); + return FALSE; } size = size / SFSHDRSIZE - 1; @@ -1501,7 +1498,7 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c { /* at least one sample + term record? */ FLUID_LOG(FLUID_WARN, _("File contains no samples")); FSKIP(SFSHDRSIZE, fd, fcbs); - return (OK); + return TRUE; } /* load all sample headers */ @@ -1524,7 +1521,7 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c FSKIP(SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */ - return (OK); + return TRUE; } /* "fixup" (inst # -> inst ptr) instrument references in preset list */ @@ -1548,7 +1545,7 @@ static int fixup_pgen(SFData *sf) { FLUID_LOG(FLUID_ERR, _("Preset %03d %03d: Invalid instrument reference"), ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum); - return (FAIL); + return FALSE; } z->instsamp = p3; } @@ -1559,7 +1556,7 @@ static int fixup_pgen(SFData *sf) p = fluid_list_next(p); } - return (OK); + return TRUE; } /* "fixup" (sample # -> sample ptr) sample references in instrument list */ @@ -1583,7 +1580,7 @@ static int fixup_igen(SFData *sf) { FLUID_LOG(FLUID_ERR, _("Instrument \"%s\": Invalid sample reference"), ((SFInst *)(p->data))->name); - return (FAIL); + return FALSE; } z->instsamp = p3; } @@ -1592,7 +1589,7 @@ static int fixup_igen(SFData *sf) p = fluid_list_next(p); } - return (OK); + return TRUE; } /* convert sample end, loopstart and loopend to offsets and check if valid */ @@ -1710,7 +1707,7 @@ static int fixup_sample(SFData *sf) FLUID_LOG(FLUID_WARN, _("Found samples with invalid loops, audible glitches possible.")); } - return (OK); + return TRUE; } /* close SoundFont file and delete a SoundFont structure */ @@ -1826,12 +1823,12 @@ static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) while (p) { if (p->data == NULL) - return (NULL); + return NULL; if (gen == ((SFGen *)p->data)->id) break; p = fluid_list_next(p); } - return (p); + return p; } /* check validity of instrument generator */ @@ -1840,7 +1837,7 @@ static int gen_valid(int gen) int i = 0; if (gen > Gen_MaxValid) - return (FALSE); + return FALSE; while (badgen[i] && badgen[i] != gen) i++; return (badgen[i] == 0); @@ -1852,7 +1849,7 @@ static int gen_validp(int gen) int i = 0; if (!gen_valid(gen)) - return (FALSE); + return FALSE; while (badpgen[i] && badpgen[i] != (unsigned short)gen) i++; return (badpgen[i] == 0); From 6fc816c3cb0b53536cfc2684a2a5e756a880d860 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 11/47] Clarify some function names and comments # Conflicts: # src/sfloader/fluid_sf2.c --- src/sfloader/fluid_sf2.c | 90 +++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index cbfb2dca..700d8903 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -73,6 +73,10 @@ enum SM24_ID }; +static const char idlist[] = {"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" + "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24"}; + + /* generator types */ typedef enum { Gen_StartAddrOfs, @@ -142,23 +146,33 @@ typedef enum { #define GenArrSize sizeof(SFGenAmount) * Gen_Count /* gen array size */ -static const unsigned short badgen[] = {Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4, - Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0}; +static const unsigned short invalid_inst_gen[] = { + Gen_Unused1, + Gen_Unused2, + Gen_Unused3, + Gen_Unused4, + Gen_Reserved1, + Gen_Reserved2, + Gen_Reserved3, + 0 +}; -static const unsigned short badpgen[] = {Gen_StartAddrOfs, - Gen_EndAddrOfs, - Gen_StartLoopAddrOfs, - Gen_EndLoopAddrOfs, - Gen_StartAddrCoarseOfs, - Gen_EndAddrCoarseOfs, - Gen_StartLoopAddrCoarseOfs, - Gen_Keynum, - Gen_Velocity, - Gen_EndLoopAddrCoarseOfs, - Gen_SampleModes, - Gen_ExclusiveClass, - Gen_OverrideRootKey, - 0}; +static const unsigned short invalid_preset_gen[] = { + Gen_StartAddrOfs, + Gen_EndAddrOfs, + Gen_StartLoopAddrOfs, + Gen_EndLoopAddrOfs, + Gen_StartAddrCoarseOfs, + Gen_EndAddrCoarseOfs, + Gen_StartLoopAddrCoarseOfs, + Gen_Keynum, + Gen_Velocity, + Gen_EndLoopAddrCoarseOfs, + Gen_SampleModes, + Gen_ExclusiveClass, + Gen_OverrideRootKey, + 0 +}; #define CHNKIDSTR(id) &idlist[(id - 1) * 4] @@ -266,14 +280,11 @@ static int fixup_igen(SFData *sf); static int fixup_sample(SFData *sf); static void sfont_free_zone(SFZone *zone); static int sfont_preset_compare_func(void *a, void *b); -static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist); -static int gen_valid(int gen); -static int gen_validp(int gen); +static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist); +static int valid_inst_genid(unsigned short genid); +static int valid_preset_genid(unsigned short genid); -static const char idlist[] = {"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD" - "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24"}; - /* sound font file load functions */ static int chunkid(unsigned int id) { @@ -999,10 +1010,10 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ else { level = 2; - if (gen_validp(genid)) + if (valid_preset_genid(genid)) { /* generator valid? */ READW(genval.sword, fd, fcbs); - dup = gen_inlist(genid, z->gen); + dup = find_gen_by_id(genid, z->gen); } else skip = TRUE; @@ -1380,10 +1391,10 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ else { level = 2; - if (gen_valid(genid)) + if (valid_inst_genid(genid)) { /* gen valid? */ READW(genval.sword, fd, fcbs); - dup = gen_inlist(genid, z->gen); + dup = find_gen_by_id(genid, z->gen); } else skip = TRUE; @@ -1814,8 +1825,11 @@ static int sfont_preset_compare_func(void *a, void *b) return (aval - bval); } -/* Find generator in gen list */ -static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) +/* Find a generator by its id in the passed in list. + * + * @return pointer to SFGen if found, otherwise NULL + */ +static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist) { /* is generator in gen list? */ fluid_list_t *p; @@ -1832,25 +1846,25 @@ static fluid_list_t *gen_inlist(int gen, fluid_list_t *genlist) } /* check validity of instrument generator */ -static int gen_valid(int gen) -{ /* is generator id valid? */ +static int valid_inst_genid(unsigned short genid) +{ int i = 0; - if (gen > Gen_MaxValid) + if (genid > Gen_MaxValid) return FALSE; - while (badgen[i] && badgen[i] != gen) + while (invalid_inst_gen[i] && invalid_inst_gen[i] != genid) i++; - return (badgen[i] == 0); + return (invalid_inst_gen[i] == 0); } /* check validity of preset generator */ -static int gen_validp(int gen) -{ /* is preset generator valid? */ +static int valid_preset_genid(unsigned short genid) +{ int i = 0; - if (!gen_valid(gen)) + if (!valid_inst_genid(genid)) return FALSE; - while (badpgen[i] && badpgen[i] != (unsigned short)gen) + while (invalid_preset_gen[i] && invalid_preset_gen[i] != genid) i++; - return (badpgen[i] == 0); + return (invalid_preset_gen[i] == 0); } From e7109a91aae70fa5de01330922a0de2a7faa38b1 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 12/47] Rename public and static methods to naming conventions # Conflicts: # src/sfloader/fluid_sf2.h --- src/sfloader/fluid_defsfont.c | 6 +++--- src/sfloader/fluid_sf2.c | 34 +++++++++++++++++----------------- src/sfloader/fluid_sf2.h | 6 +++--- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 73c7a5b3..0800604d 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -601,7 +601,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f FLUID_STRCPY(sfont->filename, file); /* The actual loading is done in the sfont and sffile files */ - sfdata = sfload_file(file, fcbs); + sfdata = fluid_sf2_load(file, fcbs); if (sfdata == NULL) { FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file"); return FLUID_FAILED; @@ -650,12 +650,12 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f fluid_defsfont_add_preset(sfont, preset); p = fluid_list_next(p); } - sfont_close (sfdata, fcbs); + fluid_sf2_close (sfdata, fcbs); return FLUID_OK; err_exit: - sfont_close (sfdata, fcbs); + fluid_sf2_close (sfdata, fcbs); delete_fluid_defpreset(preset); return FLUID_FAILED; } diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 700d8903..53272f0f 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -278,8 +278,8 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c static int fixup_pgen(SFData *sf); static int fixup_igen(SFData *sf); static int fixup_sample(SFData *sf); -static void sfont_free_zone(SFZone *zone); -static int sfont_preset_compare_func(void *a, void *b); +static void free_zone(SFZone *zone); +static int preset_compare_func(void *a, void *b); static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist); static int valid_inst_genid(unsigned short genid); static int valid_preset_genid(unsigned short genid); @@ -299,7 +299,7 @@ static int chunkid(unsigned int id) return UNKN_ID; } -SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs) +SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) { SFData *sf = NULL; void *fd; @@ -346,7 +346,7 @@ SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs) if (err) { if (sf) - sfont_close(sf, fcbs); + fluid_sf2_close(sf, fcbs); return NULL; } @@ -418,7 +418,7 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c return FALSE; /* sort preset list by bank, preset # */ - sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)sfont_preset_compare_func); + sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func); return TRUE; } @@ -519,7 +519,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac return FALSE; } - /* attach to INFO list, sfont_close will cleanup if FAIL occurs */ + /* attach to INFO list, fluid_sf2_close will cleanup if FAIL occurs */ sf->info = fluid_list_append(sf->info, item); *(unsigned char *)item = id; @@ -733,7 +733,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* load all preset headers */ p = FLUID_NEW(SFPreset); sf->preset = fluid_list_append(sf->preset, p); - p->zone = NULL; /* In case of failure, sfont_close can cleanup */ + p->zone = NULL; /* In case of failure, fluid_sf2_close can cleanup */ READSTR(&p->name, fd, fcbs); /* possible read failure ^ */ READW(p->prenum, fd, fcbs); READW(p->bank, fd, fcbs); @@ -808,7 +808,7 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ z = FLUID_NEW(SFZone); p2->data = z; z->gen = NULL; /* Init gen and mod before possible failure, */ - z->mod = NULL; /* to ensure proper cleanup (sfont_close) */ + z->mod = NULL; /* to ensure proper cleanup (fluid_sf2_close) */ READW(genndx, fd, fcbs); /* possible read failure ^ */ READW(modndx, fd, fcbs); z->instsamp = NULL; @@ -1072,7 +1072,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Discarding invalid global zone"), ((SFPreset *)(p->data))->name); *hz = fluid_list_remove(*hz, p2->data); - sfont_free_zone((SFZone *)fluid_list_get(p2)); + free_zone((SFZone *)fluid_list_get(p2)); } } @@ -1136,7 +1136,7 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* load all instrument headers */ p = FLUID_NEW(SFInst); sf->inst = fluid_list_append(sf->inst, p); - p->zone = NULL; /* For proper cleanup if fail (sfont_close) */ + p->zone = NULL; /* For proper cleanup if fail (fluid_sf2_close) */ READSTR(&p->name, fd, fcbs); /* Possible read failure ^ */ READW(zndx, fd, fcbs); @@ -1200,7 +1200,7 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ z = FLUID_NEW(SFZone); p2->data = z; z->gen = NULL; /* In case of failure, */ - z->mod = NULL; /* sfont_close can clean up */ + z->mod = NULL; /* fluid_sf2_close can clean up */ READW(genndx, fd, fcbs); /* READW = possible read failure */ READW(modndx, fd, fcbs); z->instsamp = NULL; @@ -1453,7 +1453,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Discarding invalid global zone"), ((SFInst *)(p->data))->name); *hz = fluid_list_remove(*hz, p2->data); - sfont_free_zone((SFZone *)fluid_list_get(p2)); + free_zone((SFZone *)fluid_list_get(p2)); } } @@ -1722,7 +1722,7 @@ static int fixup_sample(SFData *sf) } /* close SoundFont file and delete a SoundFont structure */ -void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs) +void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs) { fluid_list_t *p, *p2; @@ -1747,7 +1747,7 @@ void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs) p2 = ((SFPreset *)(p->data))->zone; while (p2) { /* loop over preset's zones */ - sfont_free_zone(p2->data); + free_zone(p2->data); p2 = fluid_list_next(p2); } /* free preset's zone list */ delete_fluid_list(((SFPreset *)(p->data))->zone); @@ -1763,7 +1763,7 @@ void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs) p2 = ((SFInst *)(p->data))->zone; while (p2) { /* loop over inst's zones */ - sfont_free_zone(p2->data); + free_zone(p2->data); p2 = fluid_list_next(p2); } /* free inst's zone list */ delete_fluid_list(((SFInst *)(p->data))->zone); @@ -1786,7 +1786,7 @@ void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs) } /* free all elements of a zone (Preset or Instrument) */ -static void sfont_free_zone(SFZone *zone) +static void free_zone(SFZone *zone) { fluid_list_t *p; @@ -1815,7 +1815,7 @@ static void sfont_free_zone(SFZone *zone) } /* preset sort function, first by bank, then by preset # */ -static int sfont_preset_compare_func(void *a, void *b) +static int preset_compare_func(void *a, void *b) { int aval, bval; diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h index 21209312..c452ba53 100644 --- a/src/sfloader/fluid_sf2.h +++ b/src/sfloader/fluid_sf2.h @@ -184,8 +184,8 @@ typedef struct _SFShdr unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ } SFShdr; -/* Public functions */ -SFData *sfload_file(const char *fname, const fluid_file_callbacks_t *fcbs); -void sfont_close(SFData *sf, const fluid_file_callbacks_t *fcbs); +/* Public functions */ +SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs); +void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs); #endif /* _FLUID_SF2_H */ From 500931bd338e7be71a1daa5bf92bc53bb2643427 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 13/47] Separate typedefs and struct definitons --- src/sfloader/fluid_sf2.h | 73 +++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h index c452ba53..4f6478a0 100644 --- a/src/sfloader/fluid_sf2.h +++ b/src/sfloader/fluid_sf2.h @@ -34,22 +34,39 @@ /* Sound Font structure defines */ -typedef struct _SFVersion +/* Forward declarations */ +typedef union _SFGenAmount SFGenAmount; +typedef struct _SFVersion SFVersion; +typedef struct _SFMod SFMod; +typedef struct _SFGen SFGen; +typedef struct _SFZone SFZone; +typedef struct _SFSample SFSample; +typedef struct _SFInst SFInst; +typedef struct _SFPreset SFPreset; +typedef struct _SFData SFData; +typedef struct _SFChunk SFChunk; +typedef struct _SFPhdr SFPhdr; +typedef struct _SFBag SFBag; +typedef struct _SFIhdr SFIhdr; +typedef struct _SFShdr SFShdr; + + +struct _SFVersion { /* version structure */ unsigned short major; unsigned short minor; -} SFVersion; +}; -typedef struct _SFMod +struct _SFMod { /* Modulator structure */ unsigned short src; /* source modulator */ unsigned short dest; /* destination generator */ signed short amount; /* signed, degree of modulation */ unsigned short amtsrc; /* second source controls amnt of first */ unsigned short trans; /* transform applied to source */ -} SFMod; +}; -typedef union _SFGenAmount { /* Generator amount structure */ +union _SFGenAmount { /* Generator amount structure */ signed short sword; /* signed 16 bit value */ unsigned short uword; /* unsigned 16 bit value */ struct @@ -57,22 +74,22 @@ typedef union _SFGenAmount { /* Generator amount structure */ unsigned char lo; /* low value for ranges */ unsigned char hi; /* high value for ranges */ } range; -} SFGenAmount; +}; -typedef struct _SFGen +struct _SFGen { /* Generator structure */ unsigned short id; /* generator ID */ SFGenAmount amount; /* generator value */ -} SFGen; +}; -typedef struct _SFZone +struct _SFZone { /* Sample/instrument zone structure */ fluid_list_t *instsamp; /* instrument/sample pointer for zone */ fluid_list_t *gen; /* list of generators */ fluid_list_t *mod; /* list of modulators */ -} SFZone; +}; -typedef struct _SFSample +struct _SFSample { /* Sample structure */ char name[21]; /* Name of sample */ unsigned char samfile; /* Loaded sfont/sample buffer = 0/1 */ @@ -92,15 +109,15 @@ typedef struct _SFSample signed char pitchadj; /* pitch correction in cents */ unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ fluid_sample_t *fluid_sample; /* Imported sample (fixed up in fluid_defsfont_load) */ -} SFSample; +}; -typedef struct _SFInst +struct _SFInst { /* Instrument structure */ char name[21]; /* Name of instrument */ fluid_list_t *zone; /* list of instrument zones */ -} SFInst; +}; -typedef struct _SFPreset +struct _SFPreset { /* Preset structure */ char name[21]; /* preset name */ unsigned short prenum; /* preset number */ @@ -109,10 +126,10 @@ typedef struct _SFPreset unsigned int genre; /* Not used (preserved) */ unsigned int morph; /* Not used (preserved) */ fluid_list_t *zone; /* list of preset zones */ -} SFPreset; +}; /* NOTE: sffd is also used to determine if sound font is new (NULL) */ -typedef struct _SFData +struct _SFData { /* Sound font data structure */ SFVersion version; /* sound font version */ SFVersion romver; /* ROM version */ @@ -130,7 +147,7 @@ typedef struct _SFData fluid_list_t *preset; /* linked list of preset info */ fluid_list_t *inst; /* linked list of instrument info */ fluid_list_t *sample; /* linked list of sample info */ -} SFData; +}; /* functions */ @@ -141,13 +158,13 @@ typedef struct _SFData */ /* sfont file data structures */ -typedef struct _SFChunk +struct _SFChunk { /* RIFF file chunk structure */ unsigned int id; /* chunk id */ unsigned int size; /* size of the following chunk */ -} SFChunk; +}; -typedef struct _SFPhdr +struct _SFPhdr { unsigned char name[20]; /* preset name */ unsigned short preset; /* preset number */ @@ -156,21 +173,21 @@ typedef struct _SFPhdr unsigned int library; /* just for preserving them */ unsigned int genre; /* Not used */ unsigned int morphology; /* Not used */ -} SFPhdr; +}; -typedef struct _SFBag +struct _SFBag { unsigned short genndx; /* index into generator list */ unsigned short modndx; /* index into modulator list */ -} SFBag; +}; -typedef struct _SFIhdr +struct _SFIhdr { char name[20]; /* Name of instrument */ unsigned short ibagndx; /* Instrument bag index */ -} SFIhdr; +}; -typedef struct _SFShdr +struct _SFShdr { /* Sample header loading struct */ char name[20]; /* Sample name */ unsigned int start; /* Offset to start of sample */ @@ -182,7 +199,7 @@ typedef struct _SFShdr signed char pitchadj; /* pitch correction in cents */ unsigned short samplelink; /* Not used */ unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */ -} SFShdr; +}; /* Public functions */ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs); From 78be6f7fe19cac54cd783b287b8ff6d7667e3026 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 14/47] Use FLUID_FREE instead of free --- src/sfloader/fluid_sf2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 53272f0f..ead9ee2a 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -1730,12 +1730,12 @@ void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs) fcbs->fclose(sf->sffd); if (sf->fname) - free(sf->fname); + FLUID_FREE(sf->fname); p = sf->info; while (p) { - free(p->data); + FLUID_FREE(p->data); p = fluid_list_next(p); } delete_fluid_list(sf->info); From fb374814c3a7aadbfe4b90639292889c91da7ad0 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 15/47] Move public functions to top of file and document them properly --- src/sfloader/fluid_sf2.c | 173 +++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 78 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index ead9ee2a..e43da00f 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -285,20 +285,13 @@ static int valid_inst_genid(unsigned short genid); static int valid_preset_genid(unsigned short genid); -/* sound font file load functions */ -static int chunkid(unsigned int id) -{ - unsigned int i; - unsigned int *p; - - p = (unsigned int *)&idlist; - for (i = 0; i < sizeof(idlist) / sizeof(int); i++, p += 1) - if (*p == id) - return (i + 1); - - return UNKN_ID; -} - +/* + * Open a SoundFont file and parse it's contents into a SFData structure. + * + * @param fname filename + * @param fcbs file callback structure + * @return the parsed SoundFont as SFData structure or NULL on error + */ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) { SFData *sf = NULL; @@ -353,6 +346,94 @@ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) return sf; } +/* + * Close a SoundFont file and free the SFData structure. + * + * @param sf pointer to SFData structure + * @param fcbs file callback structure + */ +void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs) +{ + fluid_list_t *p, *p2; + + if (sf->sffd) + fcbs->fclose(sf->sffd); + + if (sf->fname) + FLUID_FREE(sf->fname); + + p = sf->info; + while (p) + { + FLUID_FREE(p->data); + p = fluid_list_next(p); + } + delete_fluid_list(sf->info); + sf->info = NULL; + + p = sf->preset; + while (p) + { /* loop over presets */ + p2 = ((SFPreset *)(p->data))->zone; + while (p2) + { /* loop over preset's zones */ + free_zone(p2->data); + p2 = fluid_list_next(p2); + } /* free preset's zone list */ + delete_fluid_list(((SFPreset *)(p->data))->zone); + FLUID_FREE(p->data); /* free preset chunk */ + p = fluid_list_next(p); + } + delete_fluid_list(sf->preset); + sf->preset = NULL; + + p = sf->inst; + while (p) + { /* loop over instruments */ + p2 = ((SFInst *)(p->data))->zone; + while (p2) + { /* loop over inst's zones */ + free_zone(p2->data); + p2 = fluid_list_next(p2); + } /* free inst's zone list */ + delete_fluid_list(((SFInst *)(p->data))->zone); + 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); +} + + +/* + * Private functions + */ + +/* sound font file load functions */ +static int chunkid(unsigned int id) +{ + unsigned int i; + unsigned int *p; + + p = (unsigned int *)&idlist; + for (i = 0; i < sizeof(idlist) / sizeof(int); i++, p += 1) + if (*p == id) + return (i + 1); + + return UNKN_ID; +} + static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { SFChunk chunk; @@ -1721,70 +1802,6 @@ static int fixup_sample(SFData *sf) return TRUE; } -/* close SoundFont file and delete a SoundFont structure */ -void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs) -{ - fluid_list_t *p, *p2; - - if (sf->sffd) - fcbs->fclose(sf->sffd); - - if (sf->fname) - FLUID_FREE(sf->fname); - - p = sf->info; - while (p) - { - FLUID_FREE(p->data); - p = fluid_list_next(p); - } - delete_fluid_list(sf->info); - sf->info = NULL; - - p = sf->preset; - while (p) - { /* loop over presets */ - p2 = ((SFPreset *)(p->data))->zone; - while (p2) - { /* loop over preset's zones */ - free_zone(p2->data); - p2 = fluid_list_next(p2); - } /* free preset's zone list */ - delete_fluid_list(((SFPreset *)(p->data))->zone); - FLUID_FREE(p->data); /* free preset chunk */ - p = fluid_list_next(p); - } - delete_fluid_list(sf->preset); - sf->preset = NULL; - - p = sf->inst; - while (p) - { /* loop over instruments */ - p2 = ((SFInst *)(p->data))->zone; - while (p2) - { /* loop over inst's zones */ - free_zone(p2->data); - p2 = fluid_list_next(p2); - } /* free inst's zone list */ - delete_fluid_list(((SFInst *)(p->data))->zone); - 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) */ static void free_zone(SFZone *zone) { From 181b9727e878bcd6913840a7413cc7d393483d03 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 16/47] Cleanup error handling in fluid_sf2_load --- src/sfloader/fluid_sf2.c | 83 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index e43da00f..1710a341 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -294,56 +294,57 @@ static int valid_preset_genid(unsigned short genid); */ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) { - SFData *sf = NULL; - void *fd; + SFData *sf; int fsize = 0; - int err = FALSE; - - if ((fd = fcbs->fopen(fname)) == NULL) - { - FLUID_LOG(FLUID_ERR, _("Unable to open file \"%s\""), fname); - return NULL; - } if (!(sf = FLUID_NEW(SFData))) { FLUID_LOG(FLUID_ERR, "Out of memory"); - fclose(fd); - err = TRUE; - } - - if (!err) - { - memset(sf, 0, sizeof(SFData)); /* zero sfdata */ - sf->fname = FLUID_STRDUP(fname); /* copy file name */ - sf->sffd = fd; - } - - /* get size of file */ - if (!err && fcbs->fseek(fd, 0L, SEEK_END) == FLUID_FAILED) - { /* seek to end of file */ - err = TRUE; - FLUID_LOG(FLUID_ERR, _("Seek to end of file failed")); - } - if (!err && (fsize = fcbs->ftell(fd)) == FLUID_FAILED) - { /* position = size */ - err = TRUE; - FLUID_LOG(FLUID_ERR, _("Get end of file position failed")); - } - if (!err) - rewind(fd); - - if (!err && !load_body(fsize, sf, fd, fcbs)) - err = TRUE; /* load the sfont */ - - if (err) - { - if (sf) - fluid_sf2_close(sf, fcbs); return NULL; } + FLUID_MEMSET(sf, 0, sizeof(SFData)); + + if ((sf->sffd = fcbs->fopen(fname)) == NULL) + { + FLUID_LOG(FLUID_ERR, _("Unable to open file \"%s\""), fname); + goto error_exit; + } + + sf->fname = FLUID_STRDUP(fname); + if (sf->fname == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_exit; + } + + /* get size of file by seeking to end */ + if (fcbs->fseek(sf->sffd, 0L, SEEK_END) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, _("Seek to end of file failed")); + goto error_exit; + } + if ((fsize = fcbs->ftell(sf->sffd)) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, _("Get end of file position failed")); + goto error_exit; + } + + if (fcbs->fseek(sf->sffd, 0, SEEK_SET) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, _("Rewind to start of file failed")); + goto error_exit; + } + + if (!load_body(fsize, sf, sf->sffd, fcbs)) + { + goto error_exit; + } return sf; + +error_exit: + fluid_sf2_close(sf, fcbs); + return NULL; } /* From 9c31e96c60d883de96919e10a30d35e2f0b926ad Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 17/47] Store file_callbacks in SFData structure --- src/sfloader/fluid_defsfont.c | 4 ++-- src/sfloader/fluid_sf2.c | 8 +++++--- src/sfloader/fluid_sf2.h | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 0800604d..aa1f0e2e 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -650,12 +650,12 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f fluid_defsfont_add_preset(sfont, preset); p = fluid_list_next(p); } - fluid_sf2_close (sfdata, fcbs); + fluid_sf2_close (sfdata); return FLUID_OK; err_exit: - fluid_sf2_close (sfdata, fcbs); + fluid_sf2_close (sfdata); delete_fluid_defpreset(preset); return FLUID_FAILED; } diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 1710a341..1725d46c 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -304,6 +304,8 @@ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) } FLUID_MEMSET(sf, 0, sizeof(SFData)); + sf->fcbs = fcbs; + if ((sf->sffd = fcbs->fopen(fname)) == NULL) { FLUID_LOG(FLUID_ERR, _("Unable to open file \"%s\""), fname); @@ -343,7 +345,7 @@ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) return sf; error_exit: - fluid_sf2_close(sf, fcbs); + fluid_sf2_close(sf); return NULL; } @@ -353,12 +355,12 @@ error_exit: * @param sf pointer to SFData structure * @param fcbs file callback structure */ -void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs) +void fluid_sf2_close(SFData *sf) { fluid_list_t *p, *p2; if (sf->sffd) - fcbs->fclose(sf->sffd); + sf->fcbs->fclose(sf->sffd); if (sf->fname) FLUID_FREE(sf->fname); diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sf2.h index 4f6478a0..8c9a01aa 100644 --- a/src/sfloader/fluid_sf2.h +++ b/src/sfloader/fluid_sf2.h @@ -143,6 +143,8 @@ struct _SFData char *fname; /* file name */ FILE *sffd; /* loaded sfont file descriptor */ + const fluid_file_callbacks_t *fcbs; /* file callbacks used to read this file */ + 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 */ @@ -203,6 +205,6 @@ struct _SFShdr /* Public functions */ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs); -void fluid_sf2_close(SFData *sf, const fluid_file_callbacks_t *fcbs); +void fluid_sf2_close(SFData *sf); #endif /* _FLUID_SF2_H */ From 74e2a4b933bb4d306825c7dd29e5b91b6285cbda Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 18/47] More expressive variable names in load_phdr --- src/sfloader/fluid_sf2.c | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index 1725d46c..e58b7d9e 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -796,8 +796,8 @@ static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbac static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) { int i, i2; - SFPreset *p, *pr = NULL; /* ptr to current & previous preset */ - unsigned short zndx, pzndx = 0; + SFPreset *preset, *prev_preset = NULL; + unsigned short pbag_idx, prev_pbag_idx = 0; if (size % SFPHDRSIZE || size == 0) { @@ -815,49 +815,49 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ for (; i > 0; i--) { /* load all preset headers */ - p = FLUID_NEW(SFPreset); - sf->preset = fluid_list_append(sf->preset, p); - p->zone = NULL; /* In case of failure, fluid_sf2_close can cleanup */ - READSTR(&p->name, fd, fcbs); /* possible read failure ^ */ - READW(p->prenum, fd, fcbs); - READW(p->bank, fd, fcbs); - READW(zndx, fd, fcbs); - READD(p->libr, fd, fcbs); - READD(p->genre, fd, fcbs); - READD(p->morph, fd, fcbs); + preset = FLUID_NEW(SFPreset); + sf->preset = fluid_list_append(sf->preset, preset); + preset->zone = NULL; /* In case of failure, fluid_sf2_close can cleanup */ + READSTR(&preset->name, fd, fcbs); /* possible read failure ^ */ + READW(preset->prenum, fd, fcbs); + READW(preset->bank, fd, fcbs); + READW(pbag_idx, fd, fcbs); + READD(preset->libr, fd, fcbs); + READD(preset->genre, fd, fcbs); + READD(preset->morph, fd, fcbs); - if (pr) + if (prev_preset) { /* not first preset? */ - if (zndx < pzndx) + if (pbag_idx < prev_pbag_idx) { FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); return FALSE; } - i2 = zndx - pzndx; + i2 = pbag_idx - prev_pbag_idx; while (i2--) { - pr->zone = fluid_list_prepend(pr->zone, NULL); + prev_preset->zone = fluid_list_prepend(prev_preset->zone, NULL); } } - else if (zndx > 0) /* 1st preset, warn if ofs >0 */ - FLUID_LOG(FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx); - pr = p; /* update preset ptr */ - pzndx = zndx; + else if (pbag_idx > 0) /* 1st preset, warn if ofs >0 */ + FLUID_LOG(FLUID_WARN, _("%d preset zones not referenced, discarding"), pbag_idx); + prev_preset = preset; /* update preset ptr */ + prev_pbag_idx = pbag_idx; } FSKIP(24, fd, fcbs); - READW(zndx, fd, fcbs); /* Read terminal generator index */ + READW(pbag_idx, fd, fcbs); /* Read terminal generator index */ FSKIP(12, fd, fcbs); - if (zndx < pzndx) + if (pbag_idx < prev_pbag_idx) { FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); return FALSE; } - i2 = zndx - pzndx; + i2 = pbag_idx - prev_pbag_idx; while (i2--) { - pr->zone = fluid_list_prepend(pr->zone, NULL); + prev_preset->zone = fluid_list_prepend(prev_preset->zone, NULL); } return TRUE; From 5dc64d154482d4eff5916e188d56040cc3ab156d Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 19/47] Cleanup function signatures, passing SFData to every function Makes the whole file easier to read and gives the implementation a little more "object-oriented" feel. --- src/sfloader/fluid_sf2.c | 368 +++++++++++++++++++-------------------- 1 file changed, 184 insertions(+), 184 deletions(-) diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sf2.c index e58b7d9e..1c270481 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sf2.c @@ -186,66 +186,66 @@ static const unsigned short invalid_preset_gen[] = { #define SFSHDRSIZE 46 -#define READCHUNK(var, fd, fcbs) \ +#define READCHUNK(sf, var) \ do \ { \ - if (fcbs->fread(var, 8, fd) == FLUID_FAILED) \ + if (sf->fcbs->fread(var, 8, sf->sffd) == FLUID_FAILED) \ return FALSE; \ ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \ } while (0) -#define READD(var, fd, fcbs) \ - do \ - { \ - uint32_t _temp; \ - if (fcbs->fread(&_temp, 4, fd) == FLUID_FAILED) \ - return FALSE; \ - var = FLUID_LE32TOH(_temp); \ +#define READD(sf, var) \ + do \ + { \ + uint32_t _temp; \ + if (sf->fcbs->fread(&_temp, 4, sf->sffd) == FLUID_FAILED) \ + return FALSE; \ + var = FLUID_LE32TOH(_temp); \ } while (0) -#define READW(var, fd, fcbs) \ - do \ - { \ - uint16_t _temp; \ - if (fcbs->fread(&_temp, 2, fd) == FLUID_FAILED) \ - return FALSE; \ - var = FLUID_LE16TOH(_temp); \ +#define READW(sf, var) \ + do \ + { \ + uint16_t _temp; \ + if (sf->fcbs->fread(&_temp, 2, sf->sffd) == FLUID_FAILED) \ + return FALSE; \ + var = FLUID_LE16TOH(_temp); \ } while (0) -#define READID(var, fd, fcbs) \ - do \ - { \ - if (fcbs->fread(var, 4, fd) == FLUID_FAILED) \ - return FALSE; \ +#define READID(sf, var) \ + do \ + { \ + if (sf->fcbs->fread(var, 4, sf->sffd) == FLUID_FAILED) \ + return FALSE; \ } while (0) -#define READSTR(var, fd, fcbs) \ - do \ - { \ - if (fcbs->fread(var, 20, fd) == FLUID_FAILED) \ - return FALSE; \ - (*var)[20] = '\0'; \ +#define READSTR(sf, var) \ + do \ + { \ + if (sf->fcbs->fread(var, 20, sf->sffd) == FLUID_FAILED) \ + return FALSE; \ + (*var)[20] = '\0'; \ } while (0) -#define READB(var, fd, fcbs) \ - do \ - { \ - if (fcbs->fread(&var, 1, fd) == FLUID_FAILED) \ - return FALSE; \ +#define READB(sf, var) \ + do \ + { \ + if (sf->fcbs->fread(&var, 1, sf->sffd) == FLUID_FAILED) \ + return FALSE; \ } while (0) -#define FSKIP(size, fd, fcbs) \ - do \ - { \ - if (fcbs->fseek(fd, size, SEEK_CUR) == FLUID_FAILED) \ - return FALSE; \ +#define FSKIP(sf, size) \ + do \ + { \ + if (sf->fcbs->fseek(sf->sffd, size, SEEK_CUR) == FLUID_FAILED) \ + return FALSE; \ } while (0) -#define FSKIPW(fd, fcbs) \ - do \ - { \ - if (fcbs->fseek(fd, 2, SEEK_CUR) == FLUID_FAILED) \ - return FALSE; \ +#define FSKIPW(sf) \ + do \ + { \ + if (sf->fcbs->fseek(sf->sffd, 2, SEEK_CUR) == FLUID_FAILED) \ + return FALSE; \ } while (0) /* removes and advances a fluid_list_t pointer */ @@ -258,27 +258,27 @@ static const unsigned short invalid_preset_gen[] = { delete1_fluid_list(_temp); \ } while (0) -static int chunkid(unsigned int id); -static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t *fcbs); -static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int -pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size, void *fd, const fluid_file_callbacks_t *fcbs); -static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); -static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs); +static int load_body(SFData *sf, unsigned int size); +static int process_info(SFData *sf, int size); +static int process_sdta(SFData *sf, unsigned int size); +static int process_pdta(SFData *sf, int size); +static int load_phdr(SFData *sf, int size); +static int load_pbag(SFData *sf, int size); +static int load_pmod(SFData *sf, int size); +static int load_pgen(SFData *sf, int size); +static int load_ihdr(SFData *sf, int size); +static int load_ibag(SFData *sf, int size); +static int load_imod(SFData *sf, int size); +static int load_igen(SFData *sf, int size); +static int load_shdr(SFData *sf, unsigned int size); static int fixup_pgen(SFData *sf); static int fixup_igen(SFData *sf); static int fixup_sample(SFData *sf); static void free_zone(SFZone *zone); + +static int chunkid(unsigned int id); +static int read_listchunk(SFData *sf, SFChunk *chunk); +static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size); static int preset_compare_func(void *a, void *b); static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist); static int valid_inst_genid(unsigned short genid); @@ -337,7 +337,7 @@ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) goto error_exit; } - if (!load_body(fsize, sf, sf->sffd, fcbs)) + if (!load_body(sf, fsize)) { goto error_exit; } @@ -437,18 +437,18 @@ static int chunkid(unsigned int id) return UNKN_ID; } -static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_body(SFData *sf, unsigned int size) { SFChunk chunk; - READCHUNK(&chunk, fd, fcbs); /* load RIFF chunk */ + READCHUNK(sf, &chunk); /* load RIFF chunk */ if (chunkid(chunk.id) != RIFF_ID) { /* error if not RIFF */ FLUID_LOG(FLUID_ERR, _("Not a RIFF file")); return FALSE; } - READID(&chunk.id, fd, fcbs); /* load file ID */ + READID(sf, &chunk.id); /* load file ID */ if (chunkid(chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ FLUID_LOG(FLUID_ERR, _("Not a SoundFont file")); @@ -462,36 +462,36 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c } /* Process INFO block */ - if (!read_listchunk(&chunk, fd, fcbs)) + if (!read_listchunk(sf, &chunk)) return FALSE; if (chunkid(chunk.id) != INFO_ID) { FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting INFO chunk")); return FALSE; } - if (!process_info(chunk.size, sf, fd, fcbs)) + if (!process_info(sf, chunk.size)) return FALSE; /* Process sample chunk */ - if (!read_listchunk(&chunk, fd, fcbs)) + if (!read_listchunk(sf, &chunk)) return FALSE; if (chunkid(chunk.id) != SDTA_ID) { FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting SAMPLE chunk")); return FALSE; } - if (!process_sdta(chunk.size, sf, fd, fcbs)) + if (!process_sdta(sf, chunk.size)) return FALSE; /* process HYDRA chunk */ - if (!read_listchunk(&chunk, fd, fcbs)) + if (!read_listchunk(sf, &chunk)) return FALSE; if (chunkid(chunk.id) != PDTA_ID) { FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting HYDRA chunk")); return FALSE; } - if (!process_pdta(chunk.size, sf, fd, fcbs)) + if (!process_pdta(sf, chunk.size)) return FALSE; if (!fixup_pgen(sf)) @@ -507,20 +507,20 @@ static int load_body(unsigned int size, SFData *sf, void *fd, const fluid_file_c return TRUE; } -static int read_listchunk(SFChunk *chunk, void *fd, const fluid_file_callbacks_t *fcbs) +static int read_listchunk(SFData *sf, SFChunk *chunk) { - READCHUNK(chunk, fd, fcbs); /* read list chunk */ + READCHUNK(sf, chunk); /* read list chunk */ if (chunkid(chunk->id) != LIST_ID) /* error if ! list chunk */ { FLUID_LOG(FLUID_ERR, _("Invalid chunk id in level 0 parse")); return FALSE; } - READID(&chunk->id, fd, fcbs); /* read id string */ + READID(sf, &chunk->id); /* read id string */ chunk->size -= 4; return TRUE; } -static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int process_info(SFData *sf, int size) { SFChunk chunk; unsigned char id; @@ -529,7 +529,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac while (size > 0) { - READCHUNK(&chunk, fd, fcbs); + READCHUNK(sf, &chunk); size -= 8; id = chunkid(chunk.id); @@ -542,9 +542,9 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac return FALSE; } - READW(ver, fd, fcbs); + READW(sf, ver); sf->version.major = ver; - READW(ver, fd, fcbs); + READW(sf, ver); sf->version.minor = ver; if (sf->version.major < 2) @@ -582,9 +582,9 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac return FALSE; } - READW(ver, fd, fcbs); + READW(sf, ver); sf->romver.major = ver; - READW(ver, fd, fcbs); + READW(sf, ver); sf->romver.minor = ver; } else if (id != UNKN_ID) @@ -607,7 +607,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac sf->info = fluid_list_append(sf->info, item); *(unsigned char *)item = id; - if (fcbs->fread(&item[1], chunk.size, fd) == FLUID_FAILED) + if (sf->fcbs->fread(&item[1], chunk.size, sf->sffd) == FLUID_FAILED) return FALSE; /* force terminate info item (don't forget uint8 info ID) */ @@ -630,7 +630,7 @@ static int process_info(int size, SFData *sf, void *fd, const fluid_file_callbac return TRUE; } -static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int process_sdta(SFData *sf, unsigned int size) { SFChunk chunk; @@ -638,7 +638,7 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil return TRUE; /* no sample data? */ /* read sub chunk */ - READCHUNK(&chunk, fd, fcbs); + READCHUNK(sf, &chunk); size -= 8; if (chunkid(chunk.id) != SMPL_ID) @@ -657,12 +657,12 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil } /* sample data follows */ - sf->samplepos = fcbs->ftell(fd); + sf->samplepos = sf->fcbs->ftell(sf->sffd); /* used in fixup_sample() to check validity of sample headers */ sf->samplesize = chunk.size; - FSKIP(chunk.size, fd, fcbs); + FSKIP(sf, chunk.size); size -= chunk.size; if (sf->version.major >= 2 && sf->version.minor >= 4) @@ -671,7 +671,7 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil if (size > 8) { /* read sub chunk */ - READCHUNK(&chunk, fd, fcbs); + READCHUNK(sf, &chunk); size -= 8; if (chunkid(chunk.id) == SM24_ID) @@ -699,26 +699,26 @@ static int process_sdta(unsigned int size, SFData *sf, void *fd, const fluid_fil } /* sample data24 follows */ - sf->sample24pos = fcbs->ftell(fd); + sf->sample24pos = sf->fcbs->ftell(sf->sffd); sf->sample24size = sm24size; } } } ret: - FSKIP(size, fd, fcbs); + FSKIP(sf, size); return TRUE; } -static int pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size, void *fd, const fluid_file_callbacks_t *fcbs) +static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size) { unsigned int id; const char *expstr; expstr = CHNKIDSTR(expid); /* in case we need it */ - READCHUNK(chunk, fd, fcbs); + READCHUNK(sf, chunk); *size -= 8; if ((id = chunkid(chunk->id)) != expid) @@ -740,60 +740,60 @@ static int pdtahelper(unsigned int expid, unsigned int reclen, SFChunk *chunk, i return TRUE; } -static int process_pdta(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int process_pdta(SFData *sf, int size) { SFChunk chunk; - if (!pdtahelper(PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, PHDR_ID, SFPHDRSIZE, &chunk, &size)) return FALSE; - if (!load_phdr(chunk.size, sf, fd, fcbs)) + if (!load_phdr(sf, chunk.size)) return FALSE; - if (!pdtahelper(PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, PBAG_ID, SFBAGSIZE, &chunk, &size)) return FALSE; - if (!load_pbag(chunk.size, sf, fd, fcbs)) + if (!load_pbag(sf, chunk.size)) return FALSE; - if (!pdtahelper(PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, PMOD_ID, SFMODSIZE, &chunk, &size)) return FALSE; - if (!load_pmod(chunk.size, sf, fd, fcbs)) + if (!load_pmod(sf, chunk.size)) return FALSE; - if (!pdtahelper(PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, PGEN_ID, SFGENSIZE, &chunk, &size)) return FALSE; - if (!load_pgen(chunk.size, sf, fd, fcbs)) + if (!load_pgen(sf, chunk.size)) return FALSE; - if (!pdtahelper(IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, IHDR_ID, SFIHDRSIZE, &chunk, &size)) return FALSE; - if (!load_ihdr(chunk.size, sf, fd, fcbs)) + if (!load_ihdr(sf, chunk.size)) return FALSE; - if (!pdtahelper(IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, IBAG_ID, SFBAGSIZE, &chunk, &size)) return FALSE; - if (!load_ibag(chunk.size, sf, fd, fcbs)) + if (!load_ibag(sf, chunk.size)) return FALSE; - if (!pdtahelper(IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, IMOD_ID, SFMODSIZE, &chunk, &size)) return FALSE; - if (!load_imod(chunk.size, sf, fd, fcbs)) + if (!load_imod(sf, chunk.size)) return FALSE; - if (!pdtahelper(IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, IGEN_ID, SFGENSIZE, &chunk, &size)) return FALSE; - if (!load_igen(chunk.size, sf, fd, fcbs)) + if (!load_igen(sf, chunk.size)) return FALSE; - if (!pdtahelper(SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs)) + if (!pdtahelper(sf, SHDR_ID, SFSHDRSIZE, &chunk, &size)) return FALSE; - if (!load_shdr(chunk.size, sf, fd, fcbs)) + if (!load_shdr(sf, chunk.size)) return FALSE; return TRUE; } /* preset header loader */ -static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_phdr(SFData *sf, int size) { int i, i2; SFPreset *preset, *prev_preset = NULL; @@ -809,7 +809,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (i == 0) { /* at least one preset + term record */ FLUID_LOG(FLUID_WARN, _("File contains no presets")); - FSKIP(SFPHDRSIZE, fd, fcbs); + FSKIP(sf, SFPHDRSIZE); return TRUE; } @@ -818,13 +818,13 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ preset = FLUID_NEW(SFPreset); sf->preset = fluid_list_append(sf->preset, preset); preset->zone = NULL; /* In case of failure, fluid_sf2_close can cleanup */ - READSTR(&preset->name, fd, fcbs); /* possible read failure ^ */ - READW(preset->prenum, fd, fcbs); - READW(preset->bank, fd, fcbs); - READW(pbag_idx, fd, fcbs); - READD(preset->libr, fd, fcbs); - READD(preset->genre, fd, fcbs); - READD(preset->morph, fd, fcbs); + READSTR(sf, &preset->name); /* possible read failure ^ */ + READW(sf, preset->prenum); + READW(sf, preset->bank); + READW(sf, pbag_idx); + READD(sf, preset->libr); + READD(sf, preset->genre); + READD(sf, preset->morph); if (prev_preset) { /* not first preset? */ @@ -845,9 +845,9 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ prev_pbag_idx = pbag_idx; } - FSKIP(24, fd, fcbs); - READW(pbag_idx, fd, fcbs); /* Read terminal generator index */ - FSKIP(12, fd, fcbs); + FSKIP(sf, 24); + READW(sf, pbag_idx); /* Read terminal generator index */ + FSKIP(sf, 12); if (pbag_idx < prev_pbag_idx) { @@ -864,7 +864,7 @@ static int load_phdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } /* preset bag loader */ -static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_pbag(SFData *sf, int size) { fluid_list_t *p, *p2; SFZone *z, *pz = NULL; @@ -893,8 +893,8 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ p2->data = z; z->gen = NULL; /* Init gen and mod before possible failure, */ z->mod = NULL; /* to ensure proper cleanup (fluid_sf2_close) */ - READW(genndx, fd, fcbs); /* possible read failure ^ */ - READW(modndx, fd, fcbs); + READW(sf, genndx); /* possible read failure ^ */ + READW(sf, modndx); z->instsamp = NULL; if (pz) @@ -931,8 +931,8 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ return FALSE; } - READW(genndx, fd, fcbs); - READW(modndx, fd, fcbs); + READW(sf, genndx); + READW(sf, modndx); if (!pz) { @@ -964,7 +964,7 @@ static int load_pbag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } /* preset modulator loader */ -static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_pmod(SFData *sf, int size) { fluid_list_t *p, *p2, *p3; SFMod *m; @@ -985,11 +985,11 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } m = FLUID_NEW(SFMod); p3->data = m; - READW(m->src, fd, fcbs); - READW(m->dest, fd, fcbs); - READW(m->amount, fd, fcbs); - READW(m->amtsrc, fd, fcbs); - READW(m->trans, fd, fcbs); + READW(sf, m->src); + READW(sf, m->dest); + READW(sf, m->amount); + READW(sf, m->amtsrc); + READW(sf, m->trans); p3 = fluid_list_next(p3); } p2 = fluid_list_next(p2); @@ -1010,7 +1010,7 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); return FALSE; } - FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ + FSKIP(sf, SFMODSIZE); /* terminal mod */ return TRUE; } @@ -1027,7 +1027,7 @@ static int load_pmod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ * if a generator follows an instrument discard it * if a duplicate generator exists replace previous one * ------------------------------------------------------------------- */ -static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_pgen(SFData *sf, int size) { fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; SFZone *z; @@ -1060,15 +1060,15 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ return FALSE; } - READW(genid, fd, fcbs); + READW(sf, genid); if (genid == Gen_KeyRange) { /* nothing precedes */ if (level == 0) { level = 1; - READB(genval.range.lo, fd, fcbs); - READB(genval.range.hi, fd, fcbs); + READB(sf, genval.range.lo); + READB(sf, genval.range.hi); } else skip = TRUE; @@ -1078,8 +1078,8 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (level <= 1) { level = 2; - READB(genval.range.lo, fd, fcbs); - READB(genval.range.hi, fd, fcbs); + READB(sf, genval.range.lo); + READB(sf, genval.range.hi); } else skip = TRUE; @@ -1087,7 +1087,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ else if (genid == Gen_Instrument) { /* inst is last gen */ level = 3; - READW(genval.uword, fd, fcbs); + READW(sf, genval.uword); ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1); break; /* break out of generator loop */ } @@ -1096,7 +1096,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ level = 2; if (valid_preset_genid(genid)) { /* generator valid? */ - READW(genval.sword, fd, fcbs); + READW(sf, genval.sword); dup = find_gen_by_id(genid, z->gen); } else @@ -1122,7 +1122,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* Skip this generator */ discarded = TRUE; drop = TRUE; - FSKIPW(fd, fcbs); + FSKIPW(sf); } if (!drop) @@ -1168,7 +1168,7 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); return FALSE; } - FSKIP(SFGENSIZE, fd, fcbs); + FSKIP(sf, SFGENSIZE); SLADVREM(z->gen, p3); } @@ -1190,13 +1190,13 @@ static int load_pgen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); return FALSE; } - FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ + FSKIP(sf, SFGENSIZE); /* terminal gen */ return TRUE; } /* instrument header loader */ -static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_ihdr(SFData *sf, int size) { int i, i2; SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ @@ -1212,7 +1212,7 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (size == 0) { /* at least one preset + term record */ FLUID_LOG(FLUID_WARN, _("File contains no instruments")); - FSKIP(SFIHDRSIZE, fd, fcbs); + FSKIP(sf, SFIHDRSIZE); return TRUE; } @@ -1221,8 +1221,8 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ p = FLUID_NEW(SFInst); sf->inst = fluid_list_append(sf->inst, p); p->zone = NULL; /* For proper cleanup if fail (fluid_sf2_close) */ - READSTR(&p->name, fd, fcbs); /* Possible read failure ^ */ - READW(zndx, fd, fcbs); + READSTR(sf, &p->name); /* Possible read failure ^ */ + READW(sf, zndx); if (pr) { /* not first instrument? */ @@ -1241,8 +1241,8 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ pr = p; /* update instrument ptr */ } - FSKIP(20, fd, fcbs); - READW(zndx, fd, fcbs); + FSKIP(sf, 20); + READW(sf, zndx); if (zndx < pzndx) { @@ -1257,7 +1257,7 @@ static int load_ihdr(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } /* instrument bag loader */ -static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_ibag(SFData *sf, int size) { fluid_list_t *p, *p2; SFZone *z, *pz = NULL; @@ -1285,8 +1285,8 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ p2->data = z; z->gen = NULL; /* In case of failure, */ z->mod = NULL; /* fluid_sf2_close can clean up */ - READW(genndx, fd, fcbs); /* READW = possible read failure */ - READW(modndx, fd, fcbs); + READW(sf, genndx); /* READW = possible read failure */ + READW(sf, modndx); z->instsamp = NULL; if (pz) @@ -1323,8 +1323,8 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ return FALSE; } - READW(genndx, fd, fcbs); - READW(modndx, fd, fcbs); + READW(sf, genndx); + READW(sf, modndx); if (!pz) { /* in case that all are no zoners */ @@ -1356,7 +1356,7 @@ static int load_ibag(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } /* instrument modulator loader */ -static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_imod(SFData *sf, int size) { fluid_list_t *p, *p2, *p3; SFMod *m; @@ -1377,11 +1377,11 @@ static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ } m = FLUID_NEW(SFMod); p3->data = m; - READW(m->src, fd, fcbs); - READW(m->dest, fd, fcbs); - READW(m->amount, fd, fcbs); - READW(m->amtsrc, fd, fcbs); - READW(m->trans, fd, fcbs); + READW(sf, m->src); + READW(sf, m->dest); + READW(sf, m->amount); + READW(sf, m->amtsrc); + READW(sf, m->trans); p3 = fluid_list_next(p3); } p2 = fluid_list_next(p2); @@ -1402,13 +1402,13 @@ static int load_imod(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); return FALSE; } - FSKIP(SFMODSIZE, fd, fcbs); /* terminal mod */ + FSKIP(sf, SFMODSIZE); /* terminal mod */ return TRUE; } /* load instrument generators (see load_pgen for loading rules) */ -static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_igen(SFData *sf, int size) { fluid_list_t *p, *p2, *p3, *dup, **hz = NULL; SFZone *z; @@ -1441,15 +1441,15 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ return FALSE; } - READW(genid, fd, fcbs); + READW(sf, genid); if (genid == Gen_KeyRange) { /* nothing precedes */ if (level == 0) { level = 1; - READB(genval.range.lo, fd, fcbs); - READB(genval.range.hi, fd, fcbs); + READB(sf, genval.range.lo); + READB(sf, genval.range.hi); } else skip = TRUE; @@ -1459,8 +1459,8 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ if (level <= 1) { level = 2; - READB(genval.range.lo, fd, fcbs); - READB(genval.range.hi, fd, fcbs); + READB(sf, genval.range.lo); + READB(sf, genval.range.hi); } else skip = TRUE; @@ -1468,7 +1468,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ else if (genid == Gen_SampleId) { /* sample is last gen */ level = 3; - READW(genval.uword, fd, fcbs); + READW(sf, genval.uword); ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1); break; /* break out of generator loop */ } @@ -1477,7 +1477,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ level = 2; if (valid_inst_genid(genid)) { /* gen valid? */ - READW(genval.sword, fd, fcbs); + READW(sf, genval.sword); dup = find_gen_by_id(genid, z->gen); } else @@ -1503,7 +1503,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ { /* skip this generator */ discarded = TRUE; drop = TRUE; - FSKIPW(fd, fcbs); + FSKIPW(sf); } if (!drop) @@ -1549,7 +1549,7 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_ERR, _("Instrument generator chunk size mismatch")); return FALSE; } - FSKIP(SFGENSIZE, fd, fcbs); + FSKIP(sf, SFGENSIZE); SLADVREM(z->gen, p3); } @@ -1571,13 +1571,13 @@ static int load_igen(int size, SFData *sf, void *fd, const fluid_file_callbacks_ FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); return FALSE; } - FSKIP(SFGENSIZE, fd, fcbs); /* terminal gen */ + FSKIP(sf, SFGENSIZE); /* terminal gen */ return TRUE; } /* sample header loader */ -static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_callbacks_t *fcbs) +static int load_shdr(SFData *sf, unsigned int size) { unsigned int i; SFSample *p; @@ -1592,7 +1592,7 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c if (size == 0) { /* at least one sample + term record? */ FLUID_LOG(FLUID_WARN, _("File contains no samples")); - FSKIP(SFSHDRSIZE, fd, fcbs); + FSKIP(sf, SFSHDRSIZE); return TRUE; } @@ -1601,20 +1601,20 @@ static int load_shdr(unsigned int size, SFData *sf, void *fd, const fluid_file_c { p = FLUID_NEW(SFSample); sf->sample = fluid_list_append(sf->sample, p); - READSTR(&p->name, fd, fcbs); - READD(p->start, fd, fcbs); - READD(p->end, fd, fcbs); /* - end, loopstart and loopend */ - READD(p->loopstart, fd, fcbs); /* - will be checked and turned into */ - READD(p->loopend, fd, fcbs); /* - offsets in fixup_sample() */ - READD(p->samplerate, fd, fcbs); - READB(p->origpitch, fd, fcbs); - READB(p->pitchadj, fd, fcbs); - FSKIPW(fd, fcbs); /* skip sample link */ - READW(p->sampletype, fd, fcbs); + READSTR(sf, &p->name); + READD(sf, p->start); + READD(sf, p->end); /* - end, loopstart and loopend */ + READD(sf, p->loopstart); /* - will be checked and turned into */ + READD(sf, p->loopend); /* - offsets in fixup_sample() */ + READD(sf, p->samplerate); + READB(sf, p->origpitch); + READB(sf, p->pitchadj); + FSKIPW(sf); /* skip sample link */ + READW(sf, p->sampletype); p->samfile = 0; } - FSKIP(SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */ + FSKIP(sf, SFSHDRSIZE); /* skip terminal shdr */ return TRUE; } From 10b87e9d5497072ea865fa6dddeabbf4f5a6001d Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 20/47] Rename fluid_sf2 to fluid_sffile --- src/CMakeLists.txt | 4 ++-- src/sfloader/fluid_defsfont.h | 2 +- src/sfloader/{fluid_sf2.c => fluid_sffile.c} | 2 +- src/sfloader/{fluid_sf2.h => fluid_sffile.h} | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename src/sfloader/{fluid_sf2.c => fluid_sffile.c} (99%) rename src/sfloader/{fluid_sf2.h => fluid_sffile.h} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 15d1e7b6..c00bad90 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -129,8 +129,8 @@ set ( libfluidsynth_SOURCES sfloader/fluid_ramsfont.h sfloader/fluid_sfont.h sfloader/fluid_sfont.c - sfloader/fluid_sf2.c - sfloader/fluid_sf2.h + sfloader/fluid_sffile.c + sfloader/fluid_sffile.h rvoice/fluid_adsr_env.c rvoice/fluid_adsr_env.h rvoice/fluid_chorus.c diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index a88a1c9b..1c7a5868 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -27,7 +27,7 @@ #include "fluidsynth.h" #include "fluidsynth_priv.h" -#include "fluid_sf2.h" +#include "fluid_sffile.h" #include "fluid_list.h" #include "fluid_mod.h" #include "fluid_gen.h" diff --git a/src/sfloader/fluid_sf2.c b/src/sfloader/fluid_sffile.c similarity index 99% rename from src/sfloader/fluid_sf2.c rename to src/sfloader/fluid_sffile.c index 1c270481..f4c83b85 100644 --- a/src/sfloader/fluid_sf2.c +++ b/src/sfloader/fluid_sffile.c @@ -22,7 +22,7 @@ */ -#include "fluid_sf2.h" +#include "fluid_sffile.h" #include "fluid_sfont.h" #include "fluid_sys.h" diff --git a/src/sfloader/fluid_sf2.h b/src/sfloader/fluid_sffile.h similarity index 100% rename from src/sfloader/fluid_sf2.h rename to src/sfloader/fluid_sffile.h From 7f0932171408896dae804d6f0cfabd8652e23725 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 21/47] Make size macro names easier to read --- src/sfloader/fluid_sffile.c | 94 ++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index f4c83b85..de54accc 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -178,12 +178,12 @@ static const unsigned short invalid_preset_gen[] = { #define CHNKIDSTR(id) &idlist[(id - 1) * 4] /* sfont file chunk sizes */ -#define SFPHDRSIZE 38 -#define SFBAGSIZE 4 -#define SFMODSIZE 10 -#define SFGENSIZE 4 -#define SFIHDRSIZE 22 -#define SFSHDRSIZE 46 +#define SF_PHDR_SIZE (38) +#define SF_BAG_SIZE (4) +#define SF_MOD_SIZE (10) +#define SF_GEN_SIZE (4) +#define SF_IHDR_SIZE (22) +#define SF_SHDR_SIZE (46) #define READCHUNK(sf, var) \ @@ -744,47 +744,47 @@ static int process_pdta(SFData *sf, int size) { SFChunk chunk; - if (!pdtahelper(sf, PHDR_ID, SFPHDRSIZE, &chunk, &size)) + if (!pdtahelper(sf, PHDR_ID, SF_PHDR_SIZE, &chunk, &size)) return FALSE; if (!load_phdr(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, PBAG_ID, SFBAGSIZE, &chunk, &size)) + if (!pdtahelper(sf, PBAG_ID, SF_BAG_SIZE, &chunk, &size)) return FALSE; if (!load_pbag(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, PMOD_ID, SFMODSIZE, &chunk, &size)) + if (!pdtahelper(sf, PMOD_ID, SF_MOD_SIZE, &chunk, &size)) return FALSE; if (!load_pmod(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, PGEN_ID, SFGENSIZE, &chunk, &size)) + if (!pdtahelper(sf, PGEN_ID, SF_GEN_SIZE, &chunk, &size)) return FALSE; if (!load_pgen(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, IHDR_ID, SFIHDRSIZE, &chunk, &size)) + if (!pdtahelper(sf, IHDR_ID, SF_IHDR_SIZE, &chunk, &size)) return FALSE; if (!load_ihdr(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, IBAG_ID, SFBAGSIZE, &chunk, &size)) + if (!pdtahelper(sf, IBAG_ID, SF_BAG_SIZE, &chunk, &size)) return FALSE; if (!load_ibag(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, IMOD_ID, SFMODSIZE, &chunk, &size)) + if (!pdtahelper(sf, IMOD_ID, SF_MOD_SIZE, &chunk, &size)) return FALSE; if (!load_imod(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, IGEN_ID, SFGENSIZE, &chunk, &size)) + if (!pdtahelper(sf, IGEN_ID, SF_GEN_SIZE, &chunk, &size)) return FALSE; if (!load_igen(sf, chunk.size)) return FALSE; - if (!pdtahelper(sf, SHDR_ID, SFSHDRSIZE, &chunk, &size)) + if (!pdtahelper(sf, SHDR_ID, SF_SHDR_SIZE, &chunk, &size)) return FALSE; if (!load_shdr(sf, chunk.size)) return FALSE; @@ -799,17 +799,17 @@ static int load_phdr(SFData *sf, int size) SFPreset *preset, *prev_preset = NULL; unsigned short pbag_idx, prev_pbag_idx = 0; - if (size % SFPHDRSIZE || size == 0) + if (size % SF_PHDR_SIZE || size == 0) { FLUID_LOG(FLUID_ERR, _("Preset header chunk size is invalid")); return FALSE; } - i = size / SFPHDRSIZE - 1; + i = size / SF_PHDR_SIZE - 1; if (i == 0) { /* at least one preset + term record */ FLUID_LOG(FLUID_WARN, _("File contains no presets")); - FSKIP(sf, SFPHDRSIZE); + FSKIP(sf, SF_PHDR_SIZE); return TRUE; } @@ -872,7 +872,7 @@ static int load_pbag(SFData *sf, int size) unsigned short pgenndx = 0, pmodndx = 0; unsigned short i; - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ + if (size % SF_BAG_SIZE || size == 0) /* size is multiple of SF_BAG_SIZE? */ { FLUID_LOG(FLUID_ERR, _("Preset bag chunk size is invalid")); return FALSE; @@ -884,7 +884,7 @@ static int load_pbag(SFData *sf, int size) p2 = ((SFPreset *)(p->data))->zone; while (p2) { /* traverse preset's zones */ - if ((size -= SFBAGSIZE) < 0) + if ((size -= SF_BAG_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); return FALSE; @@ -924,7 +924,7 @@ static int load_pbag(SFData *sf, int size) p = fluid_list_next(p); } - size -= SFBAGSIZE; + size -= SF_BAG_SIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); @@ -978,7 +978,7 @@ static int load_pmod(SFData *sf, int size) p3 = ((SFZone *)(p2->data))->mod; while (p3) { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) + if ((size -= SF_MOD_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); return FALSE; @@ -1004,13 +1004,13 @@ static int load_pmod(SFData *sf, int size) if (size == 0) return TRUE; - size -= SFMODSIZE; + size -= SF_MOD_SIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); return FALSE; } - FSKIP(sf, SFMODSIZE); /* terminal mod */ + FSKIP(sf, SF_MOD_SIZE); /* terminal mod */ return TRUE; } @@ -1054,7 +1054,7 @@ static int load_pgen(SFData *sf, int size) dup = NULL; skip = FALSE; drop = FALSE; - if ((size -= SFGENSIZE) < 0) + if ((size -= SF_GEN_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); return FALSE; @@ -1163,12 +1163,12 @@ static int load_pgen(SFData *sf, int size) while (p3) { /* Kill any zones following an instrument */ discarded = TRUE; - if ((size -= SFGENSIZE) < 0) + if ((size -= SF_GEN_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); return FALSE; } - FSKIP(sf, SFGENSIZE); + FSKIP(sf, SF_GEN_SIZE); SLADVREM(z->gen, p3); } @@ -1184,13 +1184,13 @@ static int load_pgen(SFData *sf, int size) if (size == 0) return TRUE; - size -= SFGENSIZE; + size -= SF_GEN_SIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); return FALSE; } - FSKIP(sf, SFGENSIZE); /* terminal gen */ + FSKIP(sf, SF_GEN_SIZE); /* terminal gen */ return TRUE; } @@ -1202,17 +1202,17 @@ static int load_ihdr(SFData *sf, int size) SFInst *p, *pr = NULL; /* ptr to current & previous instrument */ unsigned short zndx, pzndx = 0; - if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */ + if (size % SF_IHDR_SIZE || size == 0) /* chunk size is valid? */ { FLUID_LOG(FLUID_ERR, _("Instrument header has invalid size")); return FALSE; } - size = size / SFIHDRSIZE - 1; + size = size / SF_IHDR_SIZE - 1; if (size == 0) { /* at least one preset + term record */ FLUID_LOG(FLUID_WARN, _("File contains no instruments")); - FSKIP(sf, SFIHDRSIZE); + FSKIP(sf, SF_IHDR_SIZE); return TRUE; } @@ -1264,7 +1264,7 @@ static int load_ibag(SFData *sf, int size) unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0; int i; - if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */ + if (size % SF_BAG_SIZE || size == 0) /* size is multiple of SF_BAG_SIZE? */ { FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size is invalid")); return FALSE; @@ -1276,7 +1276,7 @@ static int load_ibag(SFData *sf, int size) p2 = ((SFInst *)(p->data))->zone; while (p2) { /* load this inst's zones */ - if ((size -= SFBAGSIZE) < 0) + if ((size -= SF_BAG_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size mismatch")); return FALSE; @@ -1316,7 +1316,7 @@ static int load_ibag(SFData *sf, int size) p = fluid_list_next(p); } - size -= SFBAGSIZE; + size -= SF_BAG_SIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Instrument chunk size mismatch")); @@ -1370,7 +1370,7 @@ static int load_imod(SFData *sf, int size) p3 = ((SFZone *)(p2->data))->mod; while (p3) { /* load zone's modulators */ - if ((size -= SFMODSIZE) < 0) + if ((size -= SF_MOD_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); return FALSE; @@ -1396,13 +1396,13 @@ static int load_imod(SFData *sf, int size) if (size == 0) return TRUE; - size -= SFMODSIZE; + size -= SF_MOD_SIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); return FALSE; } - FSKIP(sf, SFMODSIZE); /* terminal mod */ + FSKIP(sf, SF_MOD_SIZE); /* terminal mod */ return TRUE; } @@ -1435,7 +1435,7 @@ static int load_igen(SFData *sf, int size) dup = NULL; skip = FALSE; drop = FALSE; - if ((size -= SFGENSIZE) < 0) + if ((size -= SF_GEN_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); return FALSE; @@ -1544,12 +1544,12 @@ static int load_igen(SFData *sf, int size) while (p3) { /* Kill any zones following a sample */ discarded = TRUE; - if ((size -= SFGENSIZE) < 0) + if ((size -= SF_GEN_SIZE) < 0) { FLUID_LOG(FLUID_ERR, _("Instrument generator chunk size mismatch")); return FALSE; } - FSKIP(sf, SFGENSIZE); + FSKIP(sf, SF_GEN_SIZE); SLADVREM(z->gen, p3); } @@ -1565,13 +1565,13 @@ static int load_igen(SFData *sf, int size) if (size == 0) return TRUE; - size -= SFGENSIZE; + size -= SF_GEN_SIZE; if (size != 0) { FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); return FALSE; } - FSKIP(sf, SFGENSIZE); /* terminal gen */ + FSKIP(sf, SF_GEN_SIZE); /* terminal gen */ return TRUE; } @@ -1582,17 +1582,17 @@ static int load_shdr(SFData *sf, unsigned int size) unsigned int i; SFSample *p; - if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ + if (size % SF_SHDR_SIZE || size == 0) /* size is multiple of SHDR size? */ { FLUID_LOG(FLUID_ERR, _("Sample header has invalid size")); return FALSE; } - size = size / SFSHDRSIZE - 1; + size = size / SF_SHDR_SIZE - 1; if (size == 0) { /* at least one sample + term record? */ FLUID_LOG(FLUID_WARN, _("File contains no samples")); - FSKIP(sf, SFSHDRSIZE); + FSKIP(sf, SF_SHDR_SIZE); return TRUE; } @@ -1614,7 +1614,7 @@ static int load_shdr(SFData *sf, unsigned int size) p->samfile = 0; } - FSKIP(sf, SFSHDRSIZE); /* skip terminal shdr */ + FSKIP(sf, SF_SHDR_SIZE); /* skip terminal shdr */ return TRUE; } From b6bdb6b059e0ae4274fe36105976e0a812435e6a Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 22/47] Cleanup delete_* functions --- src/sfloader/fluid_sffile.c | 153 +++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 63 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index de54accc..9d3b9225 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -258,6 +258,7 @@ static const unsigned short invalid_preset_gen[] = { delete1_fluid_list(_temp); \ } while (0) + static int load_body(SFData *sf, unsigned int size); static int process_info(SFData *sf, int size); static int process_sdta(SFData *sf, unsigned int size); @@ -274,7 +275,6 @@ static int load_shdr(SFData *sf, unsigned int size); static int fixup_pgen(SFData *sf); static int fixup_igen(SFData *sf); static int fixup_sample(SFData *sf); -static void free_zone(SFZone *zone); static int chunkid(unsigned int id); static int read_listchunk(SFData *sf, SFChunk *chunk); @@ -285,6 +285,11 @@ static int valid_inst_genid(unsigned short genid); static int valid_preset_genid(unsigned short genid); +static void delete_preset(SFPreset *preset); +static void delete_inst(SFInst *inst); +static void delete_zone(SFZone *zone); + + /* * Open a SoundFont file and parse it's contents into a SFData structure. * @@ -357,63 +362,50 @@ error_exit: */ void fluid_sf2_close(SFData *sf) { - fluid_list_t *p, *p2; + fluid_list_t *entry; + SFPreset *preset; + SFInst *inst; if (sf->sffd) - sf->fcbs->fclose(sf->sffd); - - if (sf->fname) - FLUID_FREE(sf->fname); - - p = sf->info; - while (p) { - FLUID_FREE(p->data); - p = fluid_list_next(p); + sf->fcbs->fclose(sf->sffd); + } + + FLUID_FREE(sf->fname); + + entry = sf->info; + while(entry) + { + FLUID_FREE(fluid_list_get(entry)); + entry = fluid_list_next(entry); } delete_fluid_list(sf->info); - sf->info = NULL; - p = sf->preset; - while (p) - { /* loop over presets */ - p2 = ((SFPreset *)(p->data))->zone; - while (p2) - { /* loop over preset's zones */ - free_zone(p2->data); - p2 = fluid_list_next(p2); - } /* free preset's zone list */ - delete_fluid_list(((SFPreset *)(p->data))->zone); - FLUID_FREE(p->data); /* free preset chunk */ - p = fluid_list_next(p); + entry = sf->preset; + while(entry) + { + preset = (SFPreset *)fluid_list_get(entry); + delete_preset(preset); + entry = fluid_list_next(entry); } delete_fluid_list(sf->preset); - sf->preset = NULL; - p = sf->inst; - while (p) - { /* loop over instruments */ - p2 = ((SFInst *)(p->data))->zone; - while (p2) - { /* loop over inst's zones */ - free_zone(p2->data); - p2 = fluid_list_next(p2); - } /* free inst's zone list */ - delete_fluid_list(((SFInst *)(p->data))->zone); - FLUID_FREE(p->data); - p = fluid_list_next(p); + entry = sf->inst; + while(entry) + { + inst = (SFInst *)fluid_list_get(entry); + delete_inst(inst); + entry = fluid_list_next(entry); } delete_fluid_list(sf->inst); - sf->inst = NULL; - p = sf->sample; - while (p) + entry = sf->sample; + while(entry) { - FLUID_FREE(p->data); - p = fluid_list_next(p); + FLUID_FREE(fluid_list_get(entry)); + entry = fluid_list_next(entry); } delete_fluid_list(sf->sample); - sf->sample = NULL; FLUID_FREE(sf); } @@ -1156,7 +1148,7 @@ static int load_pgen(SFData *sf, int size) FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Discarding invalid global zone"), ((SFPreset *)(p->data))->name); *hz = fluid_list_remove(*hz, p2->data); - free_zone((SFZone *)fluid_list_get(p2)); + delete_zone((SFZone *)fluid_list_get(p2)); } } @@ -1537,7 +1529,7 @@ static int load_igen(SFData *sf, int size) FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Discarding invalid global zone"), ((SFInst *)(p->data))->name); *hz = fluid_list_remove(*hz, p2->data); - free_zone((SFZone *)fluid_list_get(p2)); + delete_zone((SFZone *)fluid_list_get(p2)); } } @@ -1805,33 +1797,68 @@ static int fixup_sample(SFData *sf) return TRUE; } -/* free all elements of a zone (Preset or Instrument) */ -static void free_zone(SFZone *zone) +static void delete_preset(SFPreset *preset) { - fluid_list_t *p; + fluid_list_t *entry; + SFZone *zone; + + if (!preset) + return; + + entry = preset->zone; + while(entry) + { + zone = (SFZone *)fluid_list_get(entry); + delete_zone(zone); + entry = fluid_list_next(entry); + } + delete_fluid_list(preset->zone); +} + +static void delete_inst(SFInst *inst) +{ + fluid_list_t *entry; + SFZone *zone; + + if (!inst) + return; + + entry = inst->zone; + while(entry) + { + zone = (SFZone *)fluid_list_get(entry); + delete_zone(zone); + entry = fluid_list_next(entry); + } + delete_fluid_list(inst->zone); +} + + +/* Free all elements of a zone (Preset or Instrument) */ +static void delete_zone(SFZone *zone) +{ + fluid_list_t *entry; if (!zone) return; - p = zone->gen; - while (p) - { /* Free gen chunks for this zone */ - if (p->data) - FLUID_FREE(p->data); - p = fluid_list_next(p); + entry = zone->gen; + while(entry) + { + FLUID_FREE(fluid_list_get(entry)); + entry = fluid_list_next(entry); } - delete_fluid_list(zone->gen); /* free genlist */ + delete_fluid_list(zone->gen); - p = zone->mod; - while (p) - { /* Free mod chunks for this zone */ - if (p->data) - FLUID_FREE(p->data); - p = fluid_list_next(p); + entry = zone->mod; + while(entry) + { + FLUID_FREE(fluid_list_get(entry)); + entry = fluid_list_next(entry); } - delete_fluid_list(zone->mod); /* free modlist */ + delete_fluid_list(zone->mod); - FLUID_FREE(zone); /* free zone chunk */ + FLUID_FREE(zone); } /* preset sort function, first by bank, then by preset # */ From 1bc69be41bff16dda4823fe30b04a481ba6092f6 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 23/47] Rename fluid_sf2_* functions to fluid_sffile_* --- src/sfloader/fluid_defsfont.c | 6 +++--- src/sfloader/fluid_sffile.c | 16 ++++++++-------- src/sfloader/fluid_sffile.h | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index aa1f0e2e..3acead1d 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -601,7 +601,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f FLUID_STRCPY(sfont->filename, file); /* The actual loading is done in the sfont and sffile files */ - sfdata = fluid_sf2_load(file, fcbs); + sfdata = fluid_sffile_load(file, fcbs); if (sfdata == NULL) { FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file"); return FLUID_FAILED; @@ -650,12 +650,12 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f fluid_defsfont_add_preset(sfont, preset); p = fluid_list_next(p); } - fluid_sf2_close (sfdata); + fluid_sffile_close (sfdata); return FLUID_OK; err_exit: - fluid_sf2_close (sfdata); + fluid_sffile_close (sfdata); delete_fluid_defpreset(preset); return FLUID_FAILED; } diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 9d3b9225..87b715ed 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -297,7 +297,7 @@ static void delete_zone(SFZone *zone); * @param fcbs file callback structure * @return the parsed SoundFont as SFData structure or NULL on error */ -SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) +SFData *fluid_sffile_load(const char *fname, const fluid_file_callbacks_t *fcbs) { SFData *sf; int fsize = 0; @@ -350,7 +350,7 @@ SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs) return sf; error_exit: - fluid_sf2_close(sf); + fluid_sffile_close(sf); return NULL; } @@ -360,7 +360,7 @@ error_exit: * @param sf pointer to SFData structure * @param fcbs file callback structure */ -void fluid_sf2_close(SFData *sf) +void fluid_sffile_close(SFData *sf) { fluid_list_t *entry; SFPreset *preset; @@ -595,7 +595,7 @@ static int process_info(SFData *sf, int size) return FALSE; } - /* attach to INFO list, fluid_sf2_close will cleanup if FAIL occurs */ + /* attach to INFO list, fluid_sffile_close will cleanup if FAIL occurs */ sf->info = fluid_list_append(sf->info, item); *(unsigned char *)item = id; @@ -809,7 +809,7 @@ static int load_phdr(SFData *sf, int size) { /* load all preset headers */ preset = FLUID_NEW(SFPreset); sf->preset = fluid_list_append(sf->preset, preset); - preset->zone = NULL; /* In case of failure, fluid_sf2_close can cleanup */ + preset->zone = NULL; /* In case of failure, fluid_sffile_close can cleanup */ READSTR(sf, &preset->name); /* possible read failure ^ */ READW(sf, preset->prenum); READW(sf, preset->bank); @@ -884,7 +884,7 @@ static int load_pbag(SFData *sf, int size) z = FLUID_NEW(SFZone); p2->data = z; z->gen = NULL; /* Init gen and mod before possible failure, */ - z->mod = NULL; /* to ensure proper cleanup (fluid_sf2_close) */ + z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */ READW(sf, genndx); /* possible read failure ^ */ READW(sf, modndx); z->instsamp = NULL; @@ -1212,7 +1212,7 @@ static int load_ihdr(SFData *sf, int size) { /* load all instrument headers */ p = FLUID_NEW(SFInst); sf->inst = fluid_list_append(sf->inst, p); - p->zone = NULL; /* For proper cleanup if fail (fluid_sf2_close) */ + p->zone = NULL; /* For proper cleanup if fail (fluid_sffile_close) */ READSTR(sf, &p->name); /* Possible read failure ^ */ READW(sf, zndx); @@ -1276,7 +1276,7 @@ static int load_ibag(SFData *sf, int size) z = FLUID_NEW(SFZone); p2->data = z; z->gen = NULL; /* In case of failure, */ - z->mod = NULL; /* fluid_sf2_close can clean up */ + z->mod = NULL; /* fluid_sffile_close can clean up */ READW(sf, genndx); /* READW = possible read failure */ READW(sf, modndx); z->instsamp = NULL; diff --git a/src/sfloader/fluid_sffile.h b/src/sfloader/fluid_sffile.h index 8c9a01aa..ac6f6651 100644 --- a/src/sfloader/fluid_sffile.h +++ b/src/sfloader/fluid_sffile.h @@ -21,8 +21,8 @@ */ -#ifndef _FLUID_SF2_H -#define _FLUID_SF2_H +#ifndef _FLUID_SFFILE_H +#define _FLUID_SFFILE_H #include "fluid_gen.h" @@ -204,7 +204,7 @@ struct _SFShdr }; /* Public functions */ -SFData *fluid_sf2_load(const char *fname, const fluid_file_callbacks_t *fcbs); -void fluid_sf2_close(SFData *sf); +SFData *fluid_sffile_load(const char *fname, const fluid_file_callbacks_t *fcbs); +void fluid_sffile_close(SFData *sf); -#endif /* _FLUID_SF2_H */ +#endif /* _FLUID_SFFILE_H */ From 9341059b24d9477d4f81a31990aaba1637528b11 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 24/47] Remove underscore functions for log messages They were only used in soundfont loading code, so are probably a remnant from Smurf. The rest of the FluidSynth code doesn't use underscore functions, so remove them here as well for consistency. Also use single quotes in double quoted string, to remove the need for escaping chars. --- src/sfloader/fluid_defsfont.c | 10 +- src/sfloader/fluid_sffile.c | 168 +++++++++++++++++----------------- src/sfloader/fluid_sfont.c | 6 +- src/utils/fluidsynth_priv.h | 5 - 4 files changed, 92 insertions(+), 97 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 3acead1d..1ed13c77 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -2002,8 +2002,8 @@ static int uncompress_vorbis_sample(fluid_sample_t *sample) if (sample->loopend-1 > sample->end /* loopend may point one sample after valid sample data, as this one will never be played */ || sample->loopstart >= sample->loopend) { - FLUID_LOG (FLUID_DBG, _("Vorbis sample '%s' has unusable loop stop '%d'," - " setting to sample end '%d'+1"), sample->name, sample->loopend, sample->end); + FLUID_LOG (FLUID_DBG, "Vorbis sample '%s' has unusable loop stop '%d'," + " setting to sample end '%d'+1", sample->name, sample->loopend, sample->end); /* though illegal, loopend may be set to loopstart to disable loop */ /* is it worth informing the user? */ @@ -2014,15 +2014,15 @@ static int uncompress_vorbis_sample(fluid_sample_t *sample) if(sample->loopstart < sample->start || sample->loopstart >= sample->loopend) { - FLUID_LOG (FLUID_DBG, _("Vorbis sample '%s' has unusable loop start '%d'," - " setting to sample start '%d'"), sample->name, sample->loopstart, sample->start); + FLUID_LOG (FLUID_DBG, "Vorbis sample '%s' has unusable loop start '%d'," + " setting to sample start '%d'", sample->name, sample->loopstart, sample->start); sample->loopstart = sample->start; inv_loop |= TRUE; } if(inv_loop) { - FLUID_LOG (FLUID_WARN, _("Vorbis sample '%s' has invalid loop points"), sample->name); + FLUID_LOG (FLUID_WARN, "Vorbis sample '%s' has invalid loop points", sample->name); } return FLUID_OK; diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 87b715ed..37a040a1 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -313,7 +313,7 @@ SFData *fluid_sffile_load(const char *fname, const fluid_file_callbacks_t *fcbs) if ((sf->sffd = fcbs->fopen(fname)) == NULL) { - FLUID_LOG(FLUID_ERR, _("Unable to open file \"%s\""), fname); + FLUID_LOG(FLUID_ERR, "Unable to open file '%s'", fname); goto error_exit; } @@ -327,18 +327,18 @@ SFData *fluid_sffile_load(const char *fname, const fluid_file_callbacks_t *fcbs) /* get size of file by seeking to end */ if (fcbs->fseek(sf->sffd, 0L, SEEK_END) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, _("Seek to end of file failed")); + FLUID_LOG(FLUID_ERR, "Seek to end of file failed"); goto error_exit; } if ((fsize = fcbs->ftell(sf->sffd)) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, _("Get end of file position failed")); + FLUID_LOG(FLUID_ERR, "Get end of file position failed"); goto error_exit; } if (fcbs->fseek(sf->sffd, 0, SEEK_SET) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, _("Rewind to start of file failed")); + FLUID_LOG(FLUID_ERR, "Rewind to start of file failed"); goto error_exit; } @@ -436,20 +436,20 @@ static int load_body(SFData *sf, unsigned int size) READCHUNK(sf, &chunk); /* load RIFF chunk */ if (chunkid(chunk.id) != RIFF_ID) { /* error if not RIFF */ - FLUID_LOG(FLUID_ERR, _("Not a RIFF file")); + FLUID_LOG(FLUID_ERR, "Not a RIFF file"); return FALSE; } READID(sf, &chunk.id); /* load file ID */ if (chunkid(chunk.id) != SFBK_ID) { /* error if not SFBK_ID */ - FLUID_LOG(FLUID_ERR, _("Not a SoundFont file")); + FLUID_LOG(FLUID_ERR, "Not a SoundFont file"); return FALSE; } if (chunk.size != size - 8) { - FLUID_LOG(FLUID_ERR, _("SoundFont file size mismatch")); + FLUID_LOG(FLUID_ERR, "SoundFont file size mismatch"); return FALSE; } @@ -458,7 +458,7 @@ static int load_body(SFData *sf, unsigned int size) return FALSE; if (chunkid(chunk.id) != INFO_ID) { - FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting INFO chunk")); + FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting INFO chunk"); return FALSE; } if (!process_info(sf, chunk.size)) @@ -469,7 +469,7 @@ static int load_body(SFData *sf, unsigned int size) return FALSE; if (chunkid(chunk.id) != SDTA_ID) { - FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting SAMPLE chunk")); + FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting SAMPLE chunk"); return FALSE; } if (!process_sdta(sf, chunk.size)) @@ -480,7 +480,7 @@ static int load_body(SFData *sf, unsigned int size) return FALSE; if (chunkid(chunk.id) != PDTA_ID) { - FLUID_LOG(FLUID_ERR, _("Invalid ID found when expecting HYDRA chunk")); + FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting HYDRA chunk"); return FALSE; } if (!process_pdta(sf, chunk.size)) @@ -504,7 +504,7 @@ static int read_listchunk(SFData *sf, SFChunk *chunk) READCHUNK(sf, chunk); /* read list chunk */ if (chunkid(chunk->id) != LIST_ID) /* error if ! list chunk */ { - FLUID_LOG(FLUID_ERR, _("Invalid chunk id in level 0 parse")); + FLUID_LOG(FLUID_ERR, "Invalid chunk id in level 0 parse"); return FALSE; } READID(sf, &chunk->id); /* read id string */ @@ -530,7 +530,7 @@ static int process_info(SFData *sf, int size) { /* sound font version chunk? */ if (chunk.size != 4) { - FLUID_LOG(FLUID_ERR, _("Sound font version info chunk has invalid size")); + FLUID_LOG(FLUID_ERR, "Sound font version info chunk has invalid size"); return FALSE; } @@ -541,8 +541,8 @@ static int process_info(SFData *sf, int size) if (sf->version.major < 2) { - FLUID_LOG(FLUID_ERR, _("Sound font version is %d.%d which is not" - " supported, convert to version 2.0x"), + FLUID_LOG(FLUID_ERR, "Sound font version is %d.%d which is not" + " supported, convert to version 2.0x", sf->version.major, sf->version.minor); return FALSE; } @@ -551,8 +551,8 @@ static int process_info(SFData *sf, int size) { #if !LIBSNDFILE_SUPPORT FLUID_LOG(FLUID_WARN, - _("Sound font version is %d.%d but fluidsynth was compiled without" - " support for (v3.x)"), + "Sound font version is %d.%d but fluidsynth was compiled without" + " support for (v3.x)", sf->version.major, sf->version.minor); return FALSE; #endif @@ -560,8 +560,8 @@ static int process_info(SFData *sf, int size) else if (sf->version.major > 2) { FLUID_LOG(FLUID_WARN, - _("Sound font version is %d.%d which is newer than" - " what this version of fluidsynth was designed for (v2.0x)"), + "Sound font version is %d.%d which is newer than" + " what this version of fluidsynth was designed for (v2.0x)", sf->version.major, sf->version.minor); return FALSE; } @@ -570,7 +570,7 @@ static int process_info(SFData *sf, int size) { /* ROM version chunk? */ if (chunk.size != 4) { - FLUID_LOG(FLUID_ERR, _("ROM version info chunk has invalid size")); + FLUID_LOG(FLUID_ERR, "ROM version info chunk has invalid size"); return FALSE; } @@ -583,7 +583,7 @@ static int process_info(SFData *sf, int size) { if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) || (chunk.size % 2)) { - FLUID_LOG(FLUID_ERR, _("INFO sub chunk %.4s has invalid chunk size of %d bytes"), + FLUID_LOG(FLUID_ERR, "INFO sub chunk %.4s has invalid chunk size of %d bytes", &chunk.id, chunk.size); return FALSE; } @@ -607,7 +607,7 @@ static int process_info(SFData *sf, int size) } else { - FLUID_LOG(FLUID_ERR, _("Invalid chunk id in INFO chunk")); + FLUID_LOG(FLUID_ERR, "Invalid chunk id in INFO chunk"); return FALSE; } size -= chunk.size; @@ -615,7 +615,7 @@ static int process_info(SFData *sf, int size) if (size < 0) { - FLUID_LOG(FLUID_ERR, _("INFO chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "INFO chunk size mismatch"); return FALSE; } @@ -635,7 +635,7 @@ static int process_sdta(SFData *sf, unsigned int size) if (chunkid(chunk.id) != SMPL_ID) { - FLUID_LOG(FLUID_ERR, _("Expected SMPL chunk found invalid id instead")); + FLUID_LOG(FLUID_ERR, "Expected SMPL chunk found invalid id instead"); return FALSE; } @@ -644,7 +644,7 @@ static int process_sdta(SFData *sf, unsigned int size) * greater than SDTA. */ if (chunk.size > size) { - FLUID_LOG(FLUID_ERR, _("SDTA chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "SDTA chunk size mismatch"); return FALSE; } @@ -715,18 +715,18 @@ static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChu if ((id = chunkid(chunk->id)) != expid) { - FLUID_LOG(FLUID_ERR, _("Expected PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr); + FLUID_LOG(FLUID_ERR, "Expected PDTA sub-chunk '%.4s' found invalid id instead", expstr); return FALSE; } if (chunk->size % reclen) /* valid chunk size? */ { - FLUID_LOG(FLUID_ERR, _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr, reclen); + FLUID_LOG(FLUID_ERR, "'%.4s' chunk size is not a multiple of %d bytes", expstr, reclen); return FALSE; } if ((*size -= chunk->size) < 0) { - FLUID_LOG(FLUID_ERR, _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr); + FLUID_LOG(FLUID_ERR, "'%.4s' chunk size exceeds remaining PDTA chunk size", expstr); return FALSE; } return TRUE; @@ -793,14 +793,14 @@ static int load_phdr(SFData *sf, int size) if (size % SF_PHDR_SIZE || size == 0) { - FLUID_LOG(FLUID_ERR, _("Preset header chunk size is invalid")); + FLUID_LOG(FLUID_ERR, "Preset header chunk size is invalid"); return FALSE; } i = size / SF_PHDR_SIZE - 1; if (i == 0) { /* at least one preset + term record */ - FLUID_LOG(FLUID_WARN, _("File contains no presets")); + FLUID_LOG(FLUID_WARN, "File contains no presets"); FSKIP(sf, SF_PHDR_SIZE); return TRUE; } @@ -822,7 +822,7 @@ static int load_phdr(SFData *sf, int size) { /* not first preset? */ if (pbag_idx < prev_pbag_idx) { - FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Preset header indices not monotonic"); return FALSE; } i2 = pbag_idx - prev_pbag_idx; @@ -832,7 +832,7 @@ static int load_phdr(SFData *sf, int size) } } else if (pbag_idx > 0) /* 1st preset, warn if ofs >0 */ - FLUID_LOG(FLUID_WARN, _("%d preset zones not referenced, discarding"), pbag_idx); + FLUID_LOG(FLUID_WARN, "%d preset zones not referenced, discarding", pbag_idx); prev_preset = preset; /* update preset ptr */ prev_pbag_idx = pbag_idx; } @@ -843,7 +843,7 @@ static int load_phdr(SFData *sf, int size) if (pbag_idx < prev_pbag_idx) { - FLUID_LOG(FLUID_ERR, _("Preset header indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Preset header indices not monotonic"); return FALSE; } i2 = pbag_idx - prev_pbag_idx; @@ -866,7 +866,7 @@ static int load_pbag(SFData *sf, int size) if (size % SF_BAG_SIZE || size == 0) /* size is multiple of SF_BAG_SIZE? */ { - FLUID_LOG(FLUID_ERR, _("Preset bag chunk size is invalid")); + FLUID_LOG(FLUID_ERR, "Preset bag chunk size is invalid"); return FALSE; } @@ -878,7 +878,7 @@ static int load_pbag(SFData *sf, int size) { /* traverse preset's zones */ if ((size -= SF_BAG_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch"); return FALSE; } z = FLUID_NEW(SFZone); @@ -893,12 +893,12 @@ static int load_pbag(SFData *sf, int size) { /* if not first zone */ if (genndx < pgenndx) { - FLUID_LOG(FLUID_ERR, _("Preset bag generator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Preset bag generator indices not monotonic"); return FALSE; } if (modndx < pmodndx) { - FLUID_LOG(FLUID_ERR, _("Preset bag modulator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Preset bag modulator indices not monotonic"); return FALSE; } i = genndx - pgenndx; @@ -919,7 +919,7 @@ static int load_pbag(SFData *sf, int size) size -= SF_BAG_SIZE; if (size != 0) { - FLUID_LOG(FLUID_ERR, _("Preset bag chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch"); return FALSE; } @@ -929,20 +929,20 @@ static int load_pbag(SFData *sf, int size) if (!pz) { if (genndx > 0) - FLUID_LOG(FLUID_WARN, _("No preset generators and terminal index not 0")); + FLUID_LOG(FLUID_WARN, "No preset generators and terminal index not 0"); if (modndx > 0) - FLUID_LOG(FLUID_WARN, _("No preset modulators and terminal index not 0")); + FLUID_LOG(FLUID_WARN, "No preset modulators and terminal index not 0"); return TRUE; } if (genndx < pgenndx) { - FLUID_LOG(FLUID_ERR, _("Preset bag generator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Preset bag generator indices not monotonic"); return FALSE; } if (modndx < pmodndx) { - FLUID_LOG(FLUID_ERR, _("Preset bag modulator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Preset bag modulator indices not monotonic"); return FALSE; } i = genndx - pgenndx; @@ -972,7 +972,7 @@ static int load_pmod(SFData *sf, int size) { /* load zone's modulators */ if ((size -= SF_MOD_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset modulator chunk size mismatch"); return FALSE; } m = FLUID_NEW(SFMod); @@ -999,7 +999,7 @@ static int load_pmod(SFData *sf, int size) size -= SF_MOD_SIZE; if (size != 0) { - FLUID_LOG(FLUID_ERR, _("Preset modulator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset modulator chunk size mismatch"); return FALSE; } FSKIP(sf, SF_MOD_SIZE); /* terminal mod */ @@ -1048,7 +1048,7 @@ static int load_pgen(SFData *sf, int size) drop = FALSE; if ((size -= SF_GEN_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch"); return FALSE; } @@ -1136,7 +1136,7 @@ static int load_pgen(SFData *sf, int size) if (*hz != p2) { void *save = p2->data; - FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Global zone is not first zone"), + FLUID_LOG(FLUID_WARN, "Preset '%s': Global zone is not first zone", ((SFPreset *)(p->data))->name); SLADVREM(*hz, p2); *hz = fluid_list_prepend(*hz, save); @@ -1145,7 +1145,7 @@ static int load_pgen(SFData *sf, int size) } else { /* previous global zone exists, discard */ - FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Discarding invalid global zone"), + FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone", ((SFPreset *)(p->data))->name); *hz = fluid_list_remove(*hz, p2->data); delete_zone((SFZone *)fluid_list_get(p2)); @@ -1157,7 +1157,7 @@ static int load_pgen(SFData *sf, int size) discarded = TRUE; if ((size -= SF_GEN_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch"); return FALSE; } FSKIP(sf, SF_GEN_SIZE); @@ -1167,7 +1167,7 @@ static int load_pgen(SFData *sf, int size) p2 = fluid_list_next(p2); /* next zone */ } if (discarded) - FLUID_LOG(FLUID_WARN, _("Preset \"%s\": Some invalid generators were discarded"), + FLUID_LOG(FLUID_WARN, "Preset '%s': Some invalid generators were discarded", ((SFPreset *)(p->data))->name); p = fluid_list_next(p); } @@ -1179,7 +1179,7 @@ static int load_pgen(SFData *sf, int size) size -= SF_GEN_SIZE; if (size != 0) { - FLUID_LOG(FLUID_ERR, _("Preset generator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch"); return FALSE; } FSKIP(sf, SF_GEN_SIZE); /* terminal gen */ @@ -1196,14 +1196,14 @@ static int load_ihdr(SFData *sf, int size) if (size % SF_IHDR_SIZE || size == 0) /* chunk size is valid? */ { - FLUID_LOG(FLUID_ERR, _("Instrument header has invalid size")); + FLUID_LOG(FLUID_ERR, "Instrument header has invalid size"); return FALSE; } size = size / SF_IHDR_SIZE - 1; if (size == 0) { /* at least one preset + term record */ - FLUID_LOG(FLUID_WARN, _("File contains no instruments")); + FLUID_LOG(FLUID_WARN, "File contains no instruments"); FSKIP(sf, SF_IHDR_SIZE); return TRUE; } @@ -1220,7 +1220,7 @@ static int load_ihdr(SFData *sf, int size) { /* not first instrument? */ if (zndx < pzndx) { - FLUID_LOG(FLUID_ERR, _("Instrument header indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Instrument header indices not monotonic"); return FALSE; } i2 = zndx - pzndx; @@ -1228,7 +1228,7 @@ static int load_ihdr(SFData *sf, int size) pr->zone = fluid_list_prepend(pr->zone, NULL); } else if (zndx > 0) /* 1st inst, warn if ofs >0 */ - FLUID_LOG(FLUID_WARN, _("%d instrument zones not referenced, discarding"), zndx); + FLUID_LOG(FLUID_WARN, "%d instrument zones not referenced, discarding", zndx); pzndx = zndx; pr = p; /* update instrument ptr */ } @@ -1238,7 +1238,7 @@ static int load_ihdr(SFData *sf, int size) if (zndx < pzndx) { - FLUID_LOG(FLUID_ERR, _("Instrument header indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Instrument header indices not monotonic"); return FALSE; } i2 = zndx - pzndx; @@ -1258,7 +1258,7 @@ static int load_ibag(SFData *sf, int size) if (size % SF_BAG_SIZE || size == 0) /* size is multiple of SF_BAG_SIZE? */ { - FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size is invalid")); + FLUID_LOG(FLUID_ERR, "Instrument bag chunk size is invalid"); return FALSE; } @@ -1270,7 +1270,7 @@ static int load_ibag(SFData *sf, int size) { /* load this inst's zones */ if ((size -= SF_BAG_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Instrument bag chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Instrument bag chunk size mismatch"); return FALSE; } z = FLUID_NEW(SFZone); @@ -1285,12 +1285,12 @@ static int load_ibag(SFData *sf, int size) { /* if not first zone */ if (genndx < pgenndx) { - FLUID_LOG(FLUID_ERR, _("Instrument generator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Instrument generator indices not monotonic"); return FALSE; } if (modndx < pmodndx) { - FLUID_LOG(FLUID_ERR, _("Instrument modulator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Instrument modulator indices not monotonic"); return FALSE; } i = genndx - pgenndx; @@ -1311,7 +1311,7 @@ static int load_ibag(SFData *sf, int size) size -= SF_BAG_SIZE; if (size != 0) { - FLUID_LOG(FLUID_ERR, _("Instrument chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Instrument chunk size mismatch"); return FALSE; } @@ -1321,20 +1321,20 @@ static int load_ibag(SFData *sf, int size) if (!pz) { /* in case that all are no zoners */ if (genndx > 0) - FLUID_LOG(FLUID_WARN, _("No instrument generators and terminal index not 0")); + FLUID_LOG(FLUID_WARN, "No instrument generators and terminal index not 0"); if (modndx > 0) - FLUID_LOG(FLUID_WARN, _("No instrument modulators and terminal index not 0")); + FLUID_LOG(FLUID_WARN, "No instrument modulators and terminal index not 0"); return TRUE; } if (genndx < pgenndx) { - FLUID_LOG(FLUID_ERR, _("Instrument generator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Instrument generator indices not monotonic"); return FALSE; } if (modndx < pmodndx) { - FLUID_LOG(FLUID_ERR, _("Instrument modulator indices not monotonic")); + FLUID_LOG(FLUID_ERR, "Instrument modulator indices not monotonic"); return FALSE; } i = genndx - pgenndx; @@ -1364,7 +1364,7 @@ static int load_imod(SFData *sf, int size) { /* load zone's modulators */ if ((size -= SF_MOD_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Instrument modulator chunk size mismatch"); return FALSE; } m = FLUID_NEW(SFMod); @@ -1391,7 +1391,7 @@ static int load_imod(SFData *sf, int size) size -= SF_MOD_SIZE; if (size != 0) { - FLUID_LOG(FLUID_ERR, _("Instrument modulator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Instrument modulator chunk size mismatch"); return FALSE; } FSKIP(sf, SF_MOD_SIZE); /* terminal mod */ @@ -1429,7 +1429,7 @@ static int load_igen(SFData *sf, int size) drop = FALSE; if ((size -= SF_GEN_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "IGEN chunk size mismatch"); return FALSE; } @@ -1517,7 +1517,7 @@ static int load_igen(SFData *sf, int size) if (*hz != p2) { void *save = p2->data; - FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Global zone is not first zone"), + FLUID_LOG(FLUID_WARN, "Instrument '%s': Global zone is not first zone", ((SFPreset *)(p->data))->name); SLADVREM(*hz, p2); *hz = fluid_list_prepend(*hz, save); @@ -1526,7 +1526,7 @@ static int load_igen(SFData *sf, int size) } else { /* previous global zone exists, discard */ - FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Discarding invalid global zone"), + FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone", ((SFInst *)(p->data))->name); *hz = fluid_list_remove(*hz, p2->data); delete_zone((SFZone *)fluid_list_get(p2)); @@ -1538,7 +1538,7 @@ static int load_igen(SFData *sf, int size) discarded = TRUE; if ((size -= SF_GEN_SIZE) < 0) { - FLUID_LOG(FLUID_ERR, _("Instrument generator chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "Instrument generator chunk size mismatch"); return FALSE; } FSKIP(sf, SF_GEN_SIZE); @@ -1548,7 +1548,7 @@ static int load_igen(SFData *sf, int size) p2 = fluid_list_next(p2); /* next zone */ } if (discarded) - FLUID_LOG(FLUID_WARN, _("Instrument \"%s\": Some invalid generators were discarded"), + FLUID_LOG(FLUID_WARN, "Instrument '%s': Some invalid generators were discarded", ((SFInst *)(p->data))->name); p = fluid_list_next(p); } @@ -1560,7 +1560,7 @@ static int load_igen(SFData *sf, int size) size -= SF_GEN_SIZE; if (size != 0) { - FLUID_LOG(FLUID_ERR, _("IGEN chunk size mismatch")); + FLUID_LOG(FLUID_ERR, "IGEN chunk size mismatch"); return FALSE; } FSKIP(sf, SF_GEN_SIZE); /* terminal gen */ @@ -1576,14 +1576,14 @@ static int load_shdr(SFData *sf, unsigned int size) if (size % SF_SHDR_SIZE || size == 0) /* size is multiple of SHDR size? */ { - FLUID_LOG(FLUID_ERR, _("Sample header has invalid size")); + FLUID_LOG(FLUID_ERR, "Sample header has invalid size"); return FALSE; } size = size / SF_SHDR_SIZE - 1; if (size == 0) { /* at least one sample + term record? */ - FLUID_LOG(FLUID_WARN, _("File contains no samples")); + FLUID_LOG(FLUID_WARN, "File contains no samples"); FSKIP(sf, SF_SHDR_SIZE); return TRUE; } @@ -1630,7 +1630,7 @@ static int fixup_pgen(SFData *sf) p3 = fluid_list_nth(sf->inst, i - 1); if (!p3) { - FLUID_LOG(FLUID_ERR, _("Preset %03d %03d: Invalid instrument reference"), + FLUID_LOG(FLUID_ERR, "Preset %03d %03d: Invalid instrument reference", ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum); return FALSE; } @@ -1665,7 +1665,7 @@ static int fixup_igen(SFData *sf) p3 = fluid_list_nth(sf->sample, i - 1); if (!p3) { - FLUID_LOG(FLUID_ERR, _("Instrument \"%s\": Invalid sample reference"), + FLUID_LOG(FLUID_ERR, "Instrument '%s': Invalid sample reference", ((SFInst *)(p->data))->name); return FALSE; } @@ -1716,8 +1716,8 @@ static int fixup_sample(SFData *sf) * Maybe we should check for the minimum Ogg Vorbis headers size? */ if ((sam->end > max_end) || (sam->start > (sam->end - 4))) { - FLUID_LOG(FLUID_WARN, _("Sample '%s' start/end file positions are invalid," - " disabling and will not be saved"), + FLUID_LOG(FLUID_WARN, "Sample '%s' start/end file positions are invalid," + " disabling and will not be saved", sam->name); sam->start = sam->end = sam->loopstart = sam->loopend = 0; goto next_sample; @@ -1754,16 +1754,16 @@ static int fixup_sample(SFData *sf) /* force incorrect loop points into the sample range, ignore padding */ if (invalid_loopstart) { - FLUID_LOG(FLUID_DBG, _("Sample '%s' has unusable loop start '%d'," - " setting to sample start at '%d'"), + FLUID_LOG(FLUID_DBG, "Sample '%s' has unusable loop start '%d'," + " setting to sample start at '%d'", sam->name, sam->loopstart, sam->start); sam->loopstart = sam->start; } if (invalid_loopend) { - FLUID_LOG(FLUID_DBG, _("Sample '%s' has unusable loop stop '%d'," - " setting to sample stop at '%d'"), + FLUID_LOG(FLUID_DBG, "Sample '%s' has unusable loop stop '%d'," + " setting to sample stop at '%d'", sam->name, sam->loopend, sam->end); /* since at this time sam->end points after valid sample data (will correct that few * lines below), @@ -1774,8 +1774,8 @@ static int fixup_sample(SFData *sf) } else if (loopend_end_mismatch) { - FLUID_LOG(FLUID_DBG, _("Sample '%s' has invalid loop stop '%d'," - " sample stop at '%d', using it anyway"), + FLUID_LOG(FLUID_DBG, "Sample '%s' has invalid loop stop '%d'," + " sample stop at '%d', using it anyway", sam->name, sam->loopend, sam->end); } } @@ -1791,7 +1791,7 @@ static int fixup_sample(SFData *sf) if (invalid_loops) { - FLUID_LOG(FLUID_WARN, _("Found samples with invalid loops, audible glitches possible.")); + FLUID_LOG(FLUID_WARN, "Found samples with invalid loops, audible glitches possible."); } return TRUE; diff --git a/src/sfloader/fluid_sfont.c b/src/sfloader/fluid_sfont.c index 0f5bc943..703a4ca8 100644 --- a/src/sfloader/fluid_sfont.c +++ b/src/sfloader/fluid_sfont.c @@ -41,9 +41,9 @@ int safe_fread (void *buf, int count, void * fd) if (FLUID_FREAD(buf, count, 1, (FILE *)fd) != 1) { if (feof ((FILE *)fd)) - FLUID_LOG (FLUID_ERR, _("EOF while attemping to read %d bytes"), count); + FLUID_LOG (FLUID_ERR, "EOF while attemping to read %d bytes", count); else - FLUID_LOG (FLUID_ERR, _("File read failed")); + FLUID_LOG (FLUID_ERR, "File read failed"); return FLUID_FAILED; } @@ -53,7 +53,7 @@ int safe_fread (void *buf, int count, void * fd) int safe_fseek (void * fd, long ofs, int whence) { if (FLUID_FSEEK((FILE *)fd, ofs, whence) != 0) { - FLUID_LOG (FLUID_ERR, _("File seek failed with offset = %ld and whence = %d"), ofs, whence); + FLUID_LOG (FLUID_ERR, "File seek failed with offset = %ld and whence = %d", ofs, whence); return FLUID_FAILED; } return FLUID_OK; diff --git a/src/utils/fluidsynth_priv.h b/src/utils/fluidsynth_priv.h index 2bdda93b..06a6d310 100644 --- a/src/utils/fluidsynth_priv.h +++ b/src/utils/fluidsynth_priv.h @@ -316,9 +316,4 @@ do { strncpy(_dst,_src,_n); \ char* fluid_error(void); - -/* Internationalization */ -#define _(s) s - - #endif /* _FLUIDSYNTH_PRIV_H */ From 0a664e0797b0963555778fad795718ed79ebb770 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 25/47] Remove unnecessary conversion of sample pointers to offsets SFSample should provide the sample pointers as specified in the Soundfont file. If any mangling of the pointers is required, it should happen in the defsfont loader. --- src/sfloader/fluid_defsfont.c | 6 +++--- src/sfloader/fluid_sffile.c | 13 ++++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 1ed13c77..2e1f698f 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -1848,9 +1848,9 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs sample->data = sfont->sampledata; sample->data24 = sfont->sample24data; sample->start = sfsample->start; - sample->end = sfsample->start + sfsample->end; - sample->loopstart = sfsample->start + sfsample->loopstart; - sample->loopend = sfsample->start + sfsample->loopend; + sample->end = (sfsample->end > 0) ? sfsample->end - 1 : 0; /* marks last sample, contrary to SF spec. */ + sample->loopstart = sfsample->loopstart; + sample->loopend = sfsample->loopend; sample->samplerate = sfsample->samplerate; sample->origpitch = sfsample->origpitch; sample->pitchadj = sfsample->pitchadj; diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 37a040a1..cf86026c 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -1595,9 +1595,9 @@ static int load_shdr(SFData *sf, unsigned int size) sf->sample = fluid_list_append(sf->sample, p); READSTR(sf, &p->name); READD(sf, p->start); - READD(sf, p->end); /* - end, loopstart and loopend */ - READD(sf, p->loopstart); /* - will be checked and turned into */ - READD(sf, p->loopend); /* - offsets in fixup_sample() */ + READD(sf, p->end); + READD(sf, p->loopstart); + READD(sf, p->loopend); READD(sf, p->samplerate); READB(sf, p->origpitch); READB(sf, p->pitchadj); @@ -1679,7 +1679,7 @@ static int fixup_igen(SFData *sf) return TRUE; } -/* convert sample end, loopstart and loopend to offsets and check if valid */ +/* Make sure sample start/end and loopstart/loopend pointers are valid */ static int fixup_sample(SFData *sf) { fluid_list_t *p; @@ -1780,11 +1780,6 @@ static int fixup_sample(SFData *sf) } } - /* convert sample end, loopstart, loopend to offsets from sam->start */ - sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */ - sam->loopstart -= sam->start; - sam->loopend -= sam->start; - next_sample: p = fluid_list_next(p); } From 987d8a5f17e9880a3a8a3296f95f690f868d971b Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 26/47] Move vorbis decompression to fluid_sfont --- src/sfloader/fluid_defsfont.c | 160 +--------------------------------- src/sfloader/fluid_sfont.c | 133 ++++++++++++++++++++++++++++ src/sfloader/fluid_sfont.h | 1 + 3 files changed, 135 insertions(+), 159 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 2e1f698f..0b088a0b 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -27,11 +27,6 @@ #include "fluid_sys.h" #include "fluid_synth.h" -#if LIBSNDFILE_SUPPORT -#include -#endif - - /* EMU8k/10k hardware applies this factor to initial attenuation generator values set at preset and * instrument level in a soundfont. We apply this factor when loading the generator values to stay * compatible as most existing soundfonts expect exactly this (strange, non-standard) behaviour. */ @@ -1827,7 +1822,6 @@ fluid_zone_inside_range(fluid_zone_range_t* range, int key, int vel) * * SAMPLE */ -static int uncompress_vorbis_sample(fluid_sample_t *sample); /* * fluid_sample_in_rom @@ -1858,7 +1852,7 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs if (sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) { - int ret = uncompress_vorbis_sample(sample); + int ret = fluid_sample_decompress_vorbis(sample); if (sample->data == NULL || ret == FLUID_FAILED) { sample->valid = 0; @@ -1881,155 +1875,3 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs return FLUID_OK; } -#if LIBSNDFILE_SUPPORT -// virtual file access rountines to allow for handling -// samples as virtual files in memory -static sf_count_t -sfvio_get_filelen(void* user_data) -{ - fluid_sample_t *sample = (fluid_sample_t *)user_data; - - return (sf_count_t)(sample->end + 1 - sample->start); -} - -static sf_count_t -sfvio_seek(sf_count_t offset, int whence, void* user_data) -{ - fluid_sample_t *sample = (fluid_sample_t *)user_data; - - switch (whence) - { - case SEEK_SET: - sample->userdata = (void *)offset; - break; - case SEEK_CUR: - sample->userdata = (void *)((sf_count_t)sample->userdata + offset); - break; - case SEEK_END: - sample->userdata = (void *)(sfvio_get_filelen(user_data) + offset); - break; - } - - return (sf_count_t)sample->userdata; -} - -static sf_count_t -sfvio_read(void* ptr, sf_count_t count, void* user_data) -{ - fluid_sample_t *sample = (fluid_sample_t *)user_data; - sf_count_t remain = sfvio_get_filelen(user_data) - (sf_count_t)sample->userdata; - - if (count > remain) - count = remain; - - memcpy(ptr, (char *)sample->data + sample->start + (sf_count_t)sample->userdata, count); - sample->userdata = (void *)((sf_count_t)sample->userdata + count); - - return count; -} - -static sf_count_t -sfvio_tell (void* user_data) -{ - fluid_sample_t *sample = (fluid_sample_t *)user_data; - - return (sf_count_t)sample->userdata; -} - -static int uncompress_vorbis_sample(fluid_sample_t *sample) -{ - SNDFILE *sndfile; - SF_INFO sfinfo; - SF_VIRTUAL_IO sfvio = { - sfvio_get_filelen, - sfvio_seek, - sfvio_read, - NULL, - sfvio_tell - }; - short *sampledata_ogg; - int inv_loop = FALSE; - - // initialize file position indicator and SF_INFO structure - g_assert(sample->userdata == NULL); - memset(&sfinfo, 0, sizeof(sfinfo)); - - // open sample as a virtual file in memory - sndfile = sf_open_virtual(&sfvio, SFM_READ, &sfinfo, sample); - if (!sndfile) - { - FLUID_LOG(FLUID_ERR, sf_strerror(sndfile)); - return FLUID_FAILED; - } - - // empty sample - if (!sfinfo.frames || !sfinfo.channels) - { - sample->start = sample->end = - sample->loopstart = sample->loopend = - sample->valid = 0; - sample->data = NULL; - sf_close(sndfile); - return FLUID_OK; - } - - // allocate memory for uncompressed sample data stream - sampledata_ogg = (short *)FLUID_MALLOC(sfinfo.frames * sfinfo.channels * sizeof(short)); - if (!sampledata_ogg) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - sf_close(sndfile); - return FLUID_FAILED; - } - - // uncompress sample data stream - if (sf_readf_short(sndfile, sampledata_ogg, sfinfo.frames) < sfinfo.frames) - { - FLUID_FREE(sampledata_ogg); - FLUID_LOG(FLUID_ERR, sf_strerror(sndfile)); - sf_close(sndfile); - return FLUID_FAILED; - } - sf_close(sndfile); - - // point sample data to uncompressed data stream - sample->data = sampledata_ogg; - sample->auto_free = TRUE; - sample->start = 0; - sample->end = sfinfo.frames - 1; - - /* loop is fowled?? (cluck cluck :) */ - if (sample->loopend-1 > sample->end /* loopend may point one sample after valid sample data, as this one will never be played */ - || sample->loopstart >= sample->loopend) - { - FLUID_LOG (FLUID_DBG, "Vorbis sample '%s' has unusable loop stop '%d'," - " setting to sample end '%d'+1", sample->name, sample->loopend, sample->end); - - /* though illegal, loopend may be set to loopstart to disable loop */ - /* is it worth informing the user? */ - inv_loop |= (sample->loopend != sample->loopstart); - sample->loopend = sample->end+1; - } - - if(sample->loopstart < sample->start - || sample->loopstart >= sample->loopend) - { - FLUID_LOG (FLUID_DBG, "Vorbis sample '%s' has unusable loop start '%d'," - " setting to sample start '%d'", sample->name, sample->loopstart, sample->start); - sample->loopstart = sample->start; - inv_loop |= TRUE; - } - - if(inv_loop) - { - FLUID_LOG (FLUID_WARN, "Vorbis sample '%s' has invalid loop points", sample->name); - } - - return FLUID_OK; -} -#else -static int uncompress_vorbis_sample(fluid_sample_t *sample) -{ - return FLUID_FAILED; -} -#endif diff --git a/src/sfloader/fluid_sfont.c b/src/sfloader/fluid_sfont.c index 703a4ca8..1db6c0d9 100644 --- a/src/sfloader/fluid_sfont.c +++ b/src/sfloader/fluid_sfont.c @@ -21,6 +21,12 @@ #include "fluid_sfont.h" #include "fluid_sys.h" +#if LIBSNDFILE_SUPPORT +#include +#endif + + + void * default_fopen(const char * path) { return FLUID_FOPEN(path, "rb"); @@ -546,3 +552,130 @@ int fluid_sample_set_pitch(fluid_sample_t* sample, int root_key, int fine_tune) return FLUID_OK; } + + +#if LIBSNDFILE_SUPPORT + +// virtual file access rountines to allow for handling +// samples as virtual files in memory +static sf_count_t +sfvio_get_filelen(void* user_data) +{ + fluid_sample_t *sample = (fluid_sample_t *)user_data; + + return (sf_count_t)(sample->end + 1 - sample->start); +} + +static sf_count_t +sfvio_seek(sf_count_t offset, int whence, void* user_data) +{ + fluid_sample_t *sample = (fluid_sample_t *)user_data; + + switch (whence) + { + case SEEK_SET: + sample->userdata = (void *)offset; + break; + case SEEK_CUR: + sample->userdata = (void *)((sf_count_t)sample->userdata + offset); + break; + case SEEK_END: + sample->userdata = (void *)(sfvio_get_filelen(user_data) + offset); + break; + } + + return (sf_count_t)sample->userdata; +} + +static sf_count_t +sfvio_read(void* ptr, sf_count_t count, void* user_data) +{ + fluid_sample_t *sample = (fluid_sample_t *)user_data; + sf_count_t remain = sfvio_get_filelen(user_data) - (sf_count_t)sample->userdata; + + if (count > remain) + count = remain; + + memcpy(ptr, (char *)sample->data + sample->start + (sf_count_t)sample->userdata, count); + sample->userdata = (void *)((sf_count_t)sample->userdata + count); + + return count; +} + +static sf_count_t +sfvio_tell (void* user_data) +{ + fluid_sample_t *sample = (fluid_sample_t *)user_data; + + return (sf_count_t)sample->userdata; +} + +int fluid_sample_decompress_vorbis(fluid_sample_t *sample) +{ + SNDFILE *sndfile; + SF_INFO sfinfo; + SF_VIRTUAL_IO sfvio = { + sfvio_get_filelen, + sfvio_seek, + sfvio_read, + NULL, + sfvio_tell + }; + short *sampledata_ogg; + + // initialize file position indicator and SF_INFO structure + g_assert(sample->userdata == NULL); + memset(&sfinfo, 0, sizeof(sfinfo)); + + // open sample as a virtual file in memory + sndfile = sf_open_virtual(&sfvio, SFM_READ, &sfinfo, sample); + if (!sndfile) + { + FLUID_LOG(FLUID_ERR, sf_strerror(sndfile)); + return FLUID_FAILED; + } + + // empty sample + if (!sfinfo.frames || !sfinfo.channels) + { + sample->start = sample->end = + sample->loopstart = sample->loopend = + sample->valid = 0; + sample->data = NULL; + sf_close(sndfile); + return FLUID_OK; + } + + // allocate memory for uncompressed sample data stream + sampledata_ogg = (short *)FLUID_MALLOC(sfinfo.frames * sfinfo.channels * sizeof(short)); + if (!sampledata_ogg) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + sf_close(sndfile); + return FLUID_FAILED; + } + + // uncompress sample data stream + if (sf_readf_short(sndfile, sampledata_ogg, sfinfo.frames) < sfinfo.frames) + { + FLUID_FREE(sampledata_ogg); + FLUID_LOG(FLUID_ERR, sf_strerror(sndfile)); + sf_close(sndfile); + return FLUID_FAILED; + } + sf_close(sndfile); + + // point sample data to uncompressed data stream + sample->data = sampledata_ogg; + sample->auto_free = TRUE; + sample->start = 0; + sample->end = sfinfo.frames - 1; + + return FLUID_OK; +} +#else +int fluid_sample_decompress_vorbis(fluid_sample_t *sample) +{ + return FLUID_FAILED; +} +#endif diff --git a/src/sfloader/fluid_sfont.h b/src/sfloader/fluid_sfont.h index 2c83a156..b845e500 100644 --- a/src/sfloader/fluid_sfont.h +++ b/src/sfloader/fluid_sfont.h @@ -24,6 +24,7 @@ #include "fluidsynth.h" +FLUIDSYNTH_API int fluid_sample_decompress_vorbis(fluid_sample_t *sample); /* * Utility macros to access soundfonts, presets, and samples */ From 963a5e98b40bb6b29708d418554ef56fa331bdd3 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 27/47] Move sample and loop validation to fluid_sfont Makes it possible to use the same validation logic for both SF2 and SF3 samples. --- src/sfloader/fluid_defsfont.c | 28 +++----- src/sfloader/fluid_sffile.c | 118 +--------------------------------- src/sfloader/fluid_sfont.c | 113 ++++++++++++++++++++++++++++++++ src/sfloader/fluid_sfont.h | 3 + 4 files changed, 127 insertions(+), 135 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 0b088a0b..7de2ad58 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -1850,28 +1850,20 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs sample->pitchadj = sfsample->pitchadj; sample->sampletype = sfsample->sampletype; - if (sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) + if (fluid_sample_validate(sample, sfont->samplesize) == FLUID_FAILED) { - int ret = fluid_sample_decompress_vorbis(sample); - if (sample->data == NULL || ret == FLUID_FAILED) - { - sample->valid = 0; - return ret; - } + return FLUID_OK; } - if (sample->sampletype & FLUID_SAMPLETYPE_ROM) { - sample->valid = 0; - FLUID_LOG(FLUID_WARN, "Ignoring sample '%s': can't use ROM samples", sample->name); - } - else if (sample->end - sample->start < 8) { - sample->valid = 0; - FLUID_LOG(FLUID_WARN, "Ignoring sample '%s': too few sample data points", sample->name); - } - else { - sample->valid = TRUE; + if ((sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) + && fluid_sample_decompress_vorbis(sample) == FLUID_FAILED) + { + return FLUID_FAILED; } + fluid_sample_sanitize_loop(sample, sfont->samplesize); + + sample->valid = TRUE; + return FLUID_OK; } - diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index cf86026c..c6474367 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -274,7 +274,6 @@ static int load_igen(SFData *sf, int size); static int load_shdr(SFData *sf, unsigned int size); static int fixup_pgen(SFData *sf); static int fixup_igen(SFData *sf); -static int fixup_sample(SFData *sf); static int chunkid(unsigned int id); static int read_listchunk(SFData *sf, SFChunk *chunk); @@ -490,8 +489,6 @@ static int load_body(SFData *sf, unsigned int size) return FALSE; if (!fixup_igen(sf)) return FALSE; - if (!fixup_sample(sf)) - return FALSE; /* sort preset list by bank, preset # */ sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func); @@ -651,7 +648,7 @@ static int process_sdta(SFData *sf, unsigned int size) /* sample data follows */ sf->samplepos = sf->fcbs->ftell(sf->sffd); - /* used in fixup_sample() to check validity of sample headers */ + /* used to check validity of sample headers */ sf->samplesize = chunk.size; FSKIP(sf, chunk.size); @@ -1679,119 +1676,6 @@ static int fixup_igen(SFData *sf) return TRUE; } -/* Make sure sample start/end and loopstart/loopend pointers are valid */ -static int fixup_sample(SFData *sf) -{ - fluid_list_t *p; - SFSample *sam; - int invalid_loops = FALSE; - int invalid_loopstart; - int invalid_loopend, loopend_end_mismatch; - unsigned int total_bytes = sf->samplesize; - unsigned int total_samples = total_bytes / sizeof(short); - - p = sf->sample; - while (p) - { - unsigned int max_end; - - sam = (SFSample *)(p->data); - - /* Standard SoundFont files (SF2) use sample word indices for sample start and end pointers, - * but SF3 files with Ogg Vorbis compression use byte indices for start and end. */ - max_end = (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) ? total_bytes : total_samples; - - /* ROM samples are unusable for us by definition, so simply ignore them. */ - if (sam->sampletype & FLUID_SAMPLETYPE_ROM) - { - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - goto next_sample; - } - - /* If end is over the sample data chunk or sam start is greater than 4 - * less than the end (at least 4 samples). - * - * FIXME: where does this number 4 come from? And do we need a different number for SF3 - * files? - * Maybe we should check for the minimum Ogg Vorbis headers size? */ - if ((sam->end > max_end) || (sam->start > (sam->end - 4))) - { - FLUID_LOG(FLUID_WARN, "Sample '%s' start/end file positions are invalid," - " disabling and will not be saved", - sam->name); - sam->start = sam->end = sam->loopstart = sam->loopend = 0; - goto next_sample; - } - - /* The SoundFont 2.4 spec defines the loopstart index as the first sample point of the loop - */ - invalid_loopstart = (sam->loopstart < sam->start) || (sam->loopstart >= sam->loopend); - /* while loopend is the first point AFTER the last sample of the loop. - * this is as it should be. however we cannot be sure whether any of sam.loopend or sam.end - * is correct. hours of thinking through this have concluded, that it would be best practice - * to mangle with loops as little as necessary by only making sure loopend is within - * max_end. incorrect soundfont shall preferably fail loudly. */ - invalid_loopend = (sam->loopend > max_end) || (sam->loopstart >= sam->loopend); - - loopend_end_mismatch = (sam->loopend > sam->end); - - if (sam->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) - { - /* - * compressed samples get fixed up after decompression - * - * however we cant use the logic below, because uncompressed samples are stored in - * individual buffers - */ - } - else if (invalid_loopstart || invalid_loopend || - loopend_end_mismatch) /* loop is fowled?? (cluck cluck :) */ - { - /* though illegal, loopend may be set to loopstart to disable loop */ - /* is it worth informing the user? */ - invalid_loops |= (sam->loopend != sam->loopstart); - - /* force incorrect loop points into the sample range, ignore padding */ - if (invalid_loopstart) - { - FLUID_LOG(FLUID_DBG, "Sample '%s' has unusable loop start '%d'," - " setting to sample start at '%d'", - sam->name, sam->loopstart, sam->start); - sam->loopstart = sam->start; - } - - if (invalid_loopend) - { - FLUID_LOG(FLUID_DBG, "Sample '%s' has unusable loop stop '%d'," - " setting to sample stop at '%d'", - sam->name, sam->loopend, sam->end); - /* since at this time sam->end points after valid sample data (will correct that few - * lines below), - * set loopend to that first invalid sample, since it should never be played, but - * instead the last - * valid sample will be played */ - sam->loopend = sam->end; - } - else if (loopend_end_mismatch) - { - FLUID_LOG(FLUID_DBG, "Sample '%s' has invalid loop stop '%d'," - " sample stop at '%d', using it anyway", - sam->name, sam->loopend, sam->end); - } - } - - next_sample: - p = fluid_list_next(p); - } - - if (invalid_loops) - { - FLUID_LOG(FLUID_WARN, "Found samples with invalid loops, audible glitches possible."); - } - - return TRUE; -} - static void delete_preset(SFPreset *preset) { fluid_list_t *entry; diff --git a/src/sfloader/fluid_sfont.c b/src/sfloader/fluid_sfont.c index 1db6c0d9..e2be547e 100644 --- a/src/sfloader/fluid_sfont.c +++ b/src/sfloader/fluid_sfont.c @@ -554,6 +554,119 @@ int fluid_sample_set_pitch(fluid_sample_t* sample, int root_key, int fine_tune) } +/** + * Validate parameters of a sample + * + */ +int fluid_sample_validate(fluid_sample_t *sample, unsigned int buffer_size) +{ + /* ROM samples are unusable for us by definition */ + if (sample->sampletype & FLUID_SAMPLETYPE_ROM) + { + FLUID_LOG(FLUID_WARN, "Sample '%s': ROM sample ignored", sample->name); + return FLUID_FAILED; + } + + /* Ogg vorbis compressed samples in the SF3 format use byte indices for + * sample start and end pointers before decompression. Standard SF2 samples + * use sample word indices for all pointers, so use half the buffer_size + * for validation. */ + if (!(sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS)) + { + if (buffer_size % 2) + { + FLUID_LOG(FLUID_WARN, "Sample '%s': invalid buffer size", sample->name); + return FLUID_FAILED; + } + buffer_size /= 2; + } + + if ((sample->end > buffer_size) || (sample->start >= sample->end)) + { + FLUID_LOG(FLUID_WARN, "Sample '%s': invalid start/end file positions", sample->name); + return FLUID_FAILED; + } + + return TRUE; +} + +/* Check the sample loop pointers and optionally convert them to something + * usable in case they are broken. Return a boolean indicating if the pointers + * have been modified, so the user can be notified of possible audio glitches. + */ +int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int buffer_size) +{ + int modified = FALSE; + unsigned int max_end = buffer_size / 2; + /* In fluid_sample_t the sample end pointer points to the last sample, not + * to the data word after the last sample. FIXME: why? */ + unsigned int sample_end = sample->end + 1; + + /* Checking loops on compressed samples makes no sense at all and is really + * a programming error. Disable the loop to be on the safe side. */ + if (sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS) + { + FLUID_LOG(FLUID_ERR, "Sample '%s': checking loop on compressed sample, disabling loop", + sample->name); + sample->loopstart = sample->loopend = 0; + return TRUE; + } + + if (sample->loopstart == sample->loopend) + { + /* Some SoundFonts disable loops by setting loopstart = loopend. While + * technically invalid, we decided to accept those samples anyway. Just + * ensure that those two pointers are within the sampledata by setting + * them to 0. Don't set modified here, as this change has no audible + * effect. */ + sample->loopstart = sample->loopend = 0; + } + else if (sample->loopstart > sample->loopend) + { + unsigned int tmp; + + /* If loop start and end are reversed, try to swap them around and + * continue validation */ + FLUID_LOG(FLUID_DBG, "Sample '%s': reversed loop pointers '%d' - '%d', trying to fix", + sample->name, sample->loopstart, sample->loopend); + tmp = sample->loopstart; + sample->loopstart = sample->loopend; + sample->loopend = tmp; + modified = TRUE; + } + + /* The SoundFont 2.4 spec defines the loopstart index as the first sample + * point of the loop while loopend is the first point AFTER the last sample + * of the loop. However we cannot be sure whether any of loopend or end is + * correct. Hours of thinking through this have concluded that it would be + * best practice to mangle with loops as little as necessary by only making + * sure the pointers are within sample->start to max_end. Incorrect + * soundfont shall preferably fail loudly. */ + if ((sample->loopstart < sample->start) || (sample->loopstart > max_end)) + { + FLUID_LOG(FLUID_DBG, "Sample '%s': invalid loop start '%d', setting to sample start '%d'", + sample->name, sample->loopstart, sample->start); + sample->loopstart = sample->start; + modified = TRUE; + } + + if ((sample->loopend < sample->start) || (sample->loopend > max_end)) + { + FLUID_LOG(FLUID_DBG, "Sample '%s': invalid loop end '%d', setting to sample end '%d'", + sample->name, sample->loopend, sample_end); + sample->loopend = sample_end; + modified = TRUE; + } + + if ((sample->loopstart > sample_end) || (sample->loopend > sample_end)) + { + FLUID_LOG(FLUID_DBG, "Sample '%s': loop range '%d - %d' after sample end '%d', using it anyway", + sample->name, sample->loopstart, sample->loopend, sample_end); + } + + return modified; +} + #if LIBSNDFILE_SUPPORT // virtual file access rountines to allow for handling diff --git a/src/sfloader/fluid_sfont.h b/src/sfloader/fluid_sfont.h index b845e500..53f10a8c 100644 --- a/src/sfloader/fluid_sfont.h +++ b/src/sfloader/fluid_sfont.h @@ -24,7 +24,10 @@ #include "fluidsynth.h" +FLUIDSYNTH_API int fluid_sample_validate(fluid_sample_t *sample, unsigned int max_end); +FLUIDSYNTH_API int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int max_end); FLUIDSYNTH_API int fluid_sample_decompress_vorbis(fluid_sample_t *sample); + /* * Utility macros to access soundfonts, presets, and samples */ From 76102f200921fd4bdf2e48382bc659042a545660 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 28/47] Remove unnecessary fluid_sample_t::valid flag --- src/sfloader/fluid_defsfont.c | 2 -- src/sfloader/fluid_sfont.c | 6 ++---- src/sfloader/fluid_sfont.h | 1 - src/synth/fluid_voice.c | 4 ++-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 7de2ad58..cfe6ccb4 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -1863,7 +1863,5 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs fluid_sample_sanitize_loop(sample, sfont->samplesize); - sample->valid = TRUE; - return FLUID_OK; } diff --git a/src/sfloader/fluid_sfont.c b/src/sfloader/fluid_sfont.c index e2be547e..69e53ec1 100644 --- a/src/sfloader/fluid_sfont.c +++ b/src/sfloader/fluid_sfont.c @@ -504,7 +504,6 @@ fluid_sample_set_sound_data (fluid_sample_t* sample, sample->samplerate = sample_rate; sample->sampletype = FLUID_SAMPLETYPE_MONO; - sample->valid = 1; sample->auto_free = copy_data; return FLUID_OK; @@ -751,9 +750,8 @@ int fluid_sample_decompress_vorbis(fluid_sample_t *sample) // empty sample if (!sfinfo.frames || !sfinfo.channels) { - sample->start = sample->end = - sample->loopstart = sample->loopend = - sample->valid = 0; + sample->start = sample->end = 0; + sample->loopstart = sample->loopend = 0; sample->data = NULL; sf_close(sndfile); return FLUID_OK; diff --git a/src/sfloader/fluid_sfont.h b/src/sfloader/fluid_sfont.h index 53f10a8c..2ce3ee10 100644 --- a/src/sfloader/fluid_sfont.h +++ b/src/sfloader/fluid_sfont.h @@ -183,7 +183,6 @@ struct _fluid_sample_t int origpitch; /**< Original pitch (MIDI note number, 0-127) */ int pitchadj; /**< Fine pitch adjustment (+/- 99 cents) */ int sampletype; /**< Specifies the type of this sample as indicated by the #fluid_sample_type enum */ - int valid; /**< Should be TRUE if sample data is valid, FALSE otherwise (in which case it will not be synthesized) */ int auto_free; /**< TRUE if _fluid_sample_t::data and _fluid_sample_t::data24 should be freed upon sample destruction */ short* data; /**< Pointer to the sample's 16 bit PCM data */ char* data24; /**< If not NULL, pointer to the least significant byte counterparts of each sample data point in order to create 24 bit audio samples */ diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index f2659385..69623931 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -1726,8 +1726,8 @@ fluid_voice_optimize_sample(fluid_sample_t* s) double result; unsigned int i; - /* ignore ROM and other(?) invalid samples */ - if (!s->valid) return (FLUID_OK); + /* ignore disabled samples */ + if (s->start == s->end) return (FLUID_OK); if (!s->amplitude_that_reaches_noise_floor_is_valid) { /* Only once */ /* Scan the loop */ From 4ec1cfe73e0242560af8691116f1054ff209e344 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 29/47] Move sample caching code to own file fluid_samplecache.c/h --- src/CMakeLists.txt | 2 + src/sfloader/fluid_defsfont.c | 265 +---------------------------- src/sfloader/fluid_samplecache.c | 280 +++++++++++++++++++++++++++++++ src/sfloader/fluid_samplecache.h | 34 ++++ 4 files changed, 317 insertions(+), 264 deletions(-) create mode 100644 src/sfloader/fluid_samplecache.c create mode 100644 src/sfloader/fluid_samplecache.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c00bad90..02b660dd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -131,6 +131,8 @@ set ( libfluidsynth_SOURCES sfloader/fluid_sfont.c sfloader/fluid_sffile.c sfloader/fluid_sffile.h + sfloader/fluid_samplecache.c + sfloader/fluid_samplecache.h rvoice/fluid_adsr_env.c rvoice/fluid_adsr_env.h rvoice/fluid_chorus.c diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index cfe6ccb4..7e13d1fc 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -26,6 +26,7 @@ #include "fluid_sfont.h" #include "fluid_sys.h" #include "fluid_synth.h" +#include "fluid_samplecache.h" /* EMU8k/10k hardware applies this factor to initial attenuation generator values set at preset and * instrument level in a soundfont. We apply this factor when loading the generator values to stay @@ -204,270 +205,6 @@ int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, } - - -/*************************************************************** - * - * CACHED SAMPLEDATA LOADER - */ - -typedef struct _fluid_cached_sampledata_t { - struct _fluid_cached_sampledata_t *next; - - char* filename; - time_t modification_time; - int num_references; - int mlock; - - short* sampledata; - unsigned int samplesize; - - char* sample24data; - unsigned int sample24size; -} fluid_cached_sampledata_t; - -static fluid_cached_sampledata_t* all_cached_sampledata = NULL; -static fluid_mutex_t cached_sampledata_mutex = FLUID_MUTEX_INIT; - -static int fluid_get_file_modification_time(char *filename, time_t *modification_time) -{ -#if defined(WIN32) || defined(__OS2__) - *modification_time = 0; - return FLUID_OK; -#else - struct stat buf; - - if (stat(filename, &buf) == -1) { - return FLUID_FAILED; - } - - *modification_time = buf.st_mtime; - return FLUID_OK; -#endif -} - -static int fluid_cached_sampledata_load(char *filename, - unsigned int samplepos, - unsigned int samplesize, - short **sampledata, - unsigned int sample24pos, - unsigned int sample24size, - char **sample24data, - int try_mlock, - const fluid_file_callbacks_t* fcbs) -{ - fluid_file fd = NULL; - short *loaded_sampledata = NULL; - char *loaded_sample24data = NULL; - fluid_cached_sampledata_t* cached_sampledata = NULL; - time_t modification_time; - - fluid_mutex_lock(cached_sampledata_mutex); - - if (fluid_get_file_modification_time(filename, &modification_time) == FLUID_FAILED) { - FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); - modification_time = 0; - } - - for (cached_sampledata = all_cached_sampledata; cached_sampledata; cached_sampledata = cached_sampledata->next) { - if (FLUID_STRCMP(filename, cached_sampledata->filename)) - continue; - if (cached_sampledata->modification_time != modification_time) - continue; - if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) { - FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)", - cached_sampledata->samplesize, samplesize); - continue; - } - - if (try_mlock && !cached_sampledata->mlock) { - if (fluid_mlock(cached_sampledata->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 (cached_sampledata->sample24data != NULL) - if(fluid_mlock(cached_sampledata->sample24data, sample24size) != 0) - FLUID_LOG(FLUID_WARN, "Failed to pin the sample24 data to RAM; swapping is possible."); - } - - cached_sampledata->num_references++; - loaded_sampledata = cached_sampledata->sampledata; - loaded_sample24data = cached_sampledata->sample24data; - goto success_exit; - } - - fd = fcbs->fopen(filename); - if (fd == NULL) { - FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); - goto error_exit; - } - if (fcbs->fseek(fd, samplepos, SEEK_SET) == FLUID_FAILED) { - perror("error"); - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - goto error_exit; - } - - loaded_sampledata = (short*) FLUID_MALLOC(samplesize); - if (loaded_sampledata == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_exit; - } - if (fcbs->fread(loaded_sampledata, samplesize, fd) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, "Failed to read sample data"); - goto error_exit; - } - - if(sample24pos > 0) - { - if (fcbs->fseek(fd, sample24pos, SEEK_SET) == FLUID_FAILED) { - perror("error"); - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - goto error_exit; - } - - loaded_sample24data = (char*) FLUID_MALLOC(sample24size); - if (loaded_sample24data == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); - } - else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); - FLUID_FREE(loaded_sample24data); - loaded_sample24data = NULL; - } - } - - fcbs->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 the required permission. */ - cached_sampledata->mlock = 0; - if (try_mlock) { - if (fluid_mlock(loaded_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 */ - if (FLUID_IS_BIG_ENDIAN) { - unsigned char* cbuf; - unsigned char hi, lo; - unsigned int i, j; - short s; - cbuf = (unsigned char*)loaded_sampledata; - for (i = 0, j = 0; j < samplesize; i++) { - lo = cbuf[j++]; - hi = cbuf[j++]; - s = (hi << 8) | lo; - loaded_sampledata[i] = s; - } - } - - cached_sampledata->filename = FLUID_STRDUP(filename); - if (cached_sampledata->filename == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory."); - goto error_exit; - } - - cached_sampledata->modification_time = modification_time; - cached_sampledata->num_references = 1; - cached_sampledata->sampledata = loaded_sampledata; - cached_sampledata->samplesize = samplesize; - cached_sampledata->sample24data = loaded_sample24data; - cached_sampledata->sample24size = sample24size; - - cached_sampledata->next = all_cached_sampledata; - all_cached_sampledata = cached_sampledata; - - - success_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - *sampledata = loaded_sampledata; - *sample24data = loaded_sample24data; - return FLUID_OK; - - error_exit: - if (fd != NULL) { - fcbs->fclose(fd); - } - - FLUID_FREE(loaded_sampledata); - FLUID_FREE(loaded_sample24data); - - if (cached_sampledata != NULL) { - FLUID_FREE(cached_sampledata->filename); - } - FLUID_FREE(cached_sampledata); - - fluid_mutex_unlock(cached_sampledata_mutex); - *sampledata = NULL; - *sample24data = NULL; - return FLUID_FAILED; -} - -static int fluid_cached_sampledata_unload(const short *sampledata) -{ - fluid_cached_sampledata_t* prev = NULL; - fluid_cached_sampledata_t* cached_sampledata; - - fluid_mutex_lock(cached_sampledata_mutex); - cached_sampledata = all_cached_sampledata; - - while (cached_sampledata != NULL) { - if (sampledata == cached_sampledata->sampledata) { - - cached_sampledata->num_references--; - - if (cached_sampledata->num_references == 0) { - if (cached_sampledata->mlock) - { - fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize); - fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size); - } - FLUID_FREE(cached_sampledata->sampledata); - FLUID_FREE(cached_sampledata->sample24data); - FLUID_FREE(cached_sampledata->filename); - - if (prev != NULL) { - prev->next = cached_sampledata->next; - } else { - all_cached_sampledata = cached_sampledata->next; - } - - FLUID_FREE(cached_sampledata); - } - - goto success_exit; - } - - prev = cached_sampledata; - cached_sampledata = cached_sampledata->next; - } - - FLUID_LOG(FLUID_ERR, "Trying to free sampledata not found in cache."); - goto error_exit; - - success_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - return FLUID_OK; - - error_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - return FLUID_FAILED; -} - - - - /*************************************************************** * * SFONT diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c new file mode 100644 index 00000000..d290ba95 --- /dev/null +++ b/src/sfloader/fluid_samplecache.c @@ -0,0 +1,280 @@ +/* FluidSynth - A Software Synthesizer + * + * Copyright (C) 2003 Peter Hanappe and others. + * + * SoundFont file loading code borrowed from Smurf SoundFont Editor + * Copyright (C) 1999-2001 Josh Green + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + +#include "fluid_samplecache.h" +#include "fluidsynth.h" +#include "fluid_sys.h" + +/*************************************************************** + * + * CACHED SAMPLEDATA LOADER + */ + +typedef struct _fluid_cached_sampledata_t { + struct _fluid_cached_sampledata_t *next; + + char* filename; + time_t modification_time; + int num_references; + int mlock; + + short* sampledata; + unsigned int samplesize; + + char* sample24data; + unsigned int sample24size; +} fluid_cached_sampledata_t; + +static fluid_cached_sampledata_t* all_cached_sampledata = NULL; +static fluid_mutex_t cached_sampledata_mutex = FLUID_MUTEX_INIT; + +static int fluid_get_file_modification_time(char *filename, time_t *modification_time) +{ +#if defined(WIN32) || defined(__OS2__) + *modification_time = 0; + return FLUID_OK; +#else + struct stat buf; + + if (stat(filename, &buf) == -1) { + return FLUID_FAILED; + } + + *modification_time = buf.st_mtime; + return FLUID_OK; +#endif +} + +int fluid_cached_sampledata_load(char *filename, + unsigned int samplepos, unsigned int samplesize, short **sampledata, + unsigned int sample24pos, unsigned int sample24size, char **sample24data, + int try_mlock, const fluid_file_callbacks_t* fcbs) +{ + fluid_file fd = NULL; + short *loaded_sampledata = NULL; + char *loaded_sample24data = NULL; + fluid_cached_sampledata_t* cached_sampledata = NULL; + time_t modification_time; + + fluid_mutex_lock(cached_sampledata_mutex); + + if (fluid_get_file_modification_time(filename, &modification_time) == FLUID_FAILED) { + FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); + modification_time = 0; + } + + for (cached_sampledata = all_cached_sampledata; cached_sampledata; cached_sampledata = cached_sampledata->next) { + if (FLUID_STRCMP(filename, cached_sampledata->filename)) + continue; + if (cached_sampledata->modification_time != modification_time) + continue; + if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) { + FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)", + cached_sampledata->samplesize, samplesize); + continue; + } + + if (try_mlock && !cached_sampledata->mlock) { + if (fluid_mlock(cached_sampledata->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 (cached_sampledata->sample24data != NULL) + if(fluid_mlock(cached_sampledata->sample24data, sample24size) != 0) + FLUID_LOG(FLUID_WARN, "Failed to pin the sample24 data to RAM; swapping is possible."); + } + + cached_sampledata->num_references++; + loaded_sampledata = cached_sampledata->sampledata; + loaded_sample24data = cached_sampledata->sample24data; + goto success_exit; + } + + fd = fcbs->fopen(filename); + if (fd == NULL) { + FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); + goto error_exit; + } + if (fcbs->fseek(fd, samplepos, SEEK_SET) == FLUID_FAILED) { + perror("error"); + FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); + goto error_exit; + } + + loaded_sampledata = (short*) FLUID_MALLOC(samplesize); + if (loaded_sampledata == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_exit; + } + if (fcbs->fread(loaded_sampledata, samplesize, fd) == FLUID_FAILED) { + FLUID_LOG(FLUID_ERR, "Failed to read sample data"); + goto error_exit; + } + + if(sample24pos > 0) + { + if (fcbs->fseek(fd, sample24pos, SEEK_SET) == FLUID_FAILED) { + perror("error"); + FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); + goto error_exit; + } + + loaded_sample24data = (char*) FLUID_MALLOC(sample24size); + if (loaded_sample24data == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); + } + else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) { + FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); + FLUID_FREE(loaded_sample24data); + loaded_sample24data = NULL; + } + } + + fcbs->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 the required permission. */ + cached_sampledata->mlock = 0; + if (try_mlock) { + if (fluid_mlock(loaded_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 */ + if (FLUID_IS_BIG_ENDIAN) { + unsigned char* cbuf; + unsigned char hi, lo; + unsigned int i, j; + short s; + cbuf = (unsigned char*)loaded_sampledata; + for (i = 0, j = 0; j < samplesize; i++) { + lo = cbuf[j++]; + hi = cbuf[j++]; + s = (hi << 8) | lo; + loaded_sampledata[i] = s; + } + } + + cached_sampledata->filename = FLUID_STRDUP(filename); + if (cached_sampledata->filename == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory."); + goto error_exit; + } + + cached_sampledata->modification_time = modification_time; + cached_sampledata->num_references = 1; + cached_sampledata->sampledata = loaded_sampledata; + cached_sampledata->samplesize = samplesize; + cached_sampledata->sample24data = loaded_sample24data; + cached_sampledata->sample24size = sample24size; + + cached_sampledata->next = all_cached_sampledata; + all_cached_sampledata = cached_sampledata; + + + success_exit: + fluid_mutex_unlock(cached_sampledata_mutex); + *sampledata = loaded_sampledata; + *sample24data = loaded_sample24data; + return FLUID_OK; + + error_exit: + if (fd != NULL) { + fcbs->fclose(fd); + } + + FLUID_FREE(loaded_sampledata); + FLUID_FREE(loaded_sample24data); + + if (cached_sampledata != NULL) { + FLUID_FREE(cached_sampledata->filename); + } + FLUID_FREE(cached_sampledata); + + fluid_mutex_unlock(cached_sampledata_mutex); + *sampledata = NULL; + *sample24data = NULL; + return FLUID_FAILED; +} + +int fluid_cached_sampledata_unload(const short *sampledata) +{ + fluid_cached_sampledata_t* prev = NULL; + fluid_cached_sampledata_t* cached_sampledata; + + fluid_mutex_lock(cached_sampledata_mutex); + cached_sampledata = all_cached_sampledata; + + while (cached_sampledata != NULL) { + if (sampledata == cached_sampledata->sampledata) { + + cached_sampledata->num_references--; + + if (cached_sampledata->num_references == 0) { + if (cached_sampledata->mlock) + { + fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize); + fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size); + } + FLUID_FREE(cached_sampledata->sampledata); + FLUID_FREE(cached_sampledata->sample24data); + FLUID_FREE(cached_sampledata->filename); + + if (prev != NULL) { + prev->next = cached_sampledata->next; + } else { + all_cached_sampledata = cached_sampledata->next; + } + + FLUID_FREE(cached_sampledata); + } + + goto success_exit; + } + + prev = cached_sampledata; + cached_sampledata = cached_sampledata->next; + } + + FLUID_LOG(FLUID_ERR, "Trying to free sampledata not found in cache."); + goto error_exit; + + success_exit: + fluid_mutex_unlock(cached_sampledata_mutex); + return FLUID_OK; + + error_exit: + fluid_mutex_unlock(cached_sampledata_mutex); + return FLUID_FAILED; +} diff --git a/src/sfloader/fluid_samplecache.h b/src/sfloader/fluid_samplecache.h new file mode 100644 index 00000000..3b3e8e7b --- /dev/null +++ b/src/sfloader/fluid_samplecache.h @@ -0,0 +1,34 @@ +/* FluidSynth - A Software Synthesizer + * + * Copyright (C) 2003 Peter Hanappe and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + + +#ifndef _FLUID_SAMPLECACHE_H +#define _FLUID_SAMPLECACHE_H + +#include "fluid_sfont.h" + +int fluid_cached_sampledata_load(char *filename, + unsigned int samplepos, unsigned int samplesize, short **sampledata, + unsigned int sample24pos, unsigned int sample24size, char **sample24data, + int try_mlock, const fluid_file_callbacks_t* fcbs); + +int fluid_cached_sampledata_unload(const short *sampledata); + +#endif /* _FLUID_SAMPLECACHE_H */ From a274a394e0eacf44e98b6ababd588dccf4549795 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 30/47] Clang-format fluid_samplecache --- src/sfloader/fluid_samplecache.c | 429 +++++++++++++++++-------------- src/sfloader/fluid_samplecache.h | 13 +- 2 files changed, 241 insertions(+), 201 deletions(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index d290ba95..fa4e6bc0 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -22,259 +22,294 @@ */ #include "fluid_samplecache.h" -#include "fluidsynth.h" #include "fluid_sys.h" +#include "fluidsynth.h" /*************************************************************** * * CACHED SAMPLEDATA LOADER */ -typedef struct _fluid_cached_sampledata_t { - struct _fluid_cached_sampledata_t *next; +typedef struct _fluid_cached_sampledata_t +{ + struct _fluid_cached_sampledata_t *next; - char* filename; - time_t modification_time; - int num_references; - int mlock; + char *filename; + time_t modification_time; + int num_references; + int mlock; - short* sampledata; - unsigned int samplesize; - - char* sample24data; - unsigned int sample24size; + short *sampledata; + unsigned int samplesize; + + char *sample24data; + unsigned int sample24size; } fluid_cached_sampledata_t; -static fluid_cached_sampledata_t* all_cached_sampledata = NULL; +static fluid_cached_sampledata_t *all_cached_sampledata = NULL; static fluid_mutex_t cached_sampledata_mutex = FLUID_MUTEX_INIT; static int fluid_get_file_modification_time(char *filename, time_t *modification_time) { #if defined(WIN32) || defined(__OS2__) - *modification_time = 0; - return FLUID_OK; + *modification_time = 0; + return FLUID_OK; #else - struct stat buf; + struct stat buf; - if (stat(filename, &buf) == -1) { - return FLUID_FAILED; - } + if (stat(filename, &buf) == -1) + { + return FLUID_FAILED; + } - *modification_time = buf.st_mtime; - return FLUID_OK; + *modification_time = buf.st_mtime; + return FLUID_OK; #endif } int fluid_cached_sampledata_load(char *filename, - unsigned int samplepos, unsigned int samplesize, short **sampledata, - unsigned int sample24pos, unsigned int sample24size, char **sample24data, - int try_mlock, const fluid_file_callbacks_t* fcbs) + unsigned int samplepos, + unsigned int samplesize, + short **sampledata, + unsigned int sample24pos, + unsigned int sample24size, + char **sample24data, + int try_mlock, + const fluid_file_callbacks_t *fcbs) { - fluid_file fd = NULL; - short *loaded_sampledata = NULL; - char *loaded_sample24data = NULL; - fluid_cached_sampledata_t* cached_sampledata = NULL; - time_t modification_time; + fluid_file fd = NULL; + short *loaded_sampledata = NULL; + char *loaded_sample24data = NULL; + fluid_cached_sampledata_t *cached_sampledata = NULL; + time_t modification_time; - fluid_mutex_lock(cached_sampledata_mutex); + fluid_mutex_lock(cached_sampledata_mutex); - if (fluid_get_file_modification_time(filename, &modification_time) == FLUID_FAILED) { - FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); - modification_time = 0; - } - - for (cached_sampledata = all_cached_sampledata; cached_sampledata; cached_sampledata = cached_sampledata->next) { - if (FLUID_STRCMP(filename, cached_sampledata->filename)) - continue; - if (cached_sampledata->modification_time != modification_time) - continue; - if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) { - FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)", - cached_sampledata->samplesize, samplesize); - continue; + if (fluid_get_file_modification_time(filename, &modification_time) == FLUID_FAILED) + { + FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); + modification_time = 0; } - if (try_mlock && !cached_sampledata->mlock) { - if (fluid_mlock(cached_sampledata->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 (cached_sampledata->sample24data != NULL) - if(fluid_mlock(cached_sampledata->sample24data, sample24size) != 0) - FLUID_LOG(FLUID_WARN, "Failed to pin the sample24 data to RAM; swapping is possible."); + for (cached_sampledata = all_cached_sampledata; cached_sampledata; + cached_sampledata = cached_sampledata->next) + { + if (FLUID_STRCMP(filename, cached_sampledata->filename)) + continue; + if (cached_sampledata->modification_time != modification_time) + continue; + if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) + { + FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont " + "(cached: %u. actual: %u)", + cached_sampledata->samplesize, samplesize); + continue; + } + + if (try_mlock && !cached_sampledata->mlock) + { + if (fluid_mlock(cached_sampledata->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 (cached_sampledata->sample24data != NULL) + if (fluid_mlock(cached_sampledata->sample24data, sample24size) != 0) + FLUID_LOG(FLUID_WARN, + "Failed to pin the sample24 data to RAM; swapping is possible."); + } + + cached_sampledata->num_references++; + loaded_sampledata = cached_sampledata->sampledata; + loaded_sample24data = cached_sampledata->sample24data; + goto success_exit; } - cached_sampledata->num_references++; - loaded_sampledata = cached_sampledata->sampledata; - loaded_sample24data = cached_sampledata->sample24data; - goto success_exit; - } - - fd = fcbs->fopen(filename); - if (fd == NULL) { - FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); - goto error_exit; - } - if (fcbs->fseek(fd, samplepos, SEEK_SET) == FLUID_FAILED) { - perror("error"); - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - goto error_exit; - } - - loaded_sampledata = (short*) FLUID_MALLOC(samplesize); - if (loaded_sampledata == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_exit; - } - if (fcbs->fread(loaded_sampledata, samplesize, fd) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, "Failed to read sample data"); - goto error_exit; - } - - if(sample24pos > 0) - { - if (fcbs->fseek(fd, sample24pos, SEEK_SET) == FLUID_FAILED) { + fd = fcbs->fopen(filename); + if (fd == NULL) + { + FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); + goto error_exit; + } + if (fcbs->fseek(fd, samplepos, SEEK_SET) == FLUID_FAILED) + { perror("error"); FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); goto error_exit; } - - loaded_sample24data = (char*) FLUID_MALLOC(sample24size); - if (loaded_sample24data == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); + + loaded_sampledata = (short *)FLUID_MALLOC(samplesize); + if (loaded_sampledata == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_exit; } - else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); - FLUID_FREE(loaded_sample24data); - loaded_sample24data = NULL; + if (fcbs->fread(loaded_sampledata, samplesize, fd) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, "Failed to read sample data"); + goto error_exit; } - } - - fcbs->fclose(fd); - fd = NULL; + if (sample24pos > 0) + { + if (fcbs->fseek(fd, sample24pos, SEEK_SET) == FLUID_FAILED) + { + perror("error"); + FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); + goto error_exit; + } - 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 the required permission. */ - cached_sampledata->mlock = 0; - if (try_mlock) { - if (fluid_mlock(loaded_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 */ - if (FLUID_IS_BIG_ENDIAN) { - unsigned char* cbuf; - unsigned char hi, lo; - unsigned int i, j; - short s; - cbuf = (unsigned char*)loaded_sampledata; - for (i = 0, j = 0; j < samplesize; i++) { - lo = cbuf[j++]; - hi = cbuf[j++]; - s = (hi << 8) | lo; - loaded_sampledata[i] = s; + loaded_sample24data = (char *)FLUID_MALLOC(sample24size); + if (loaded_sample24data == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); + } + else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); + FLUID_FREE(loaded_sample24data); + loaded_sample24data = NULL; + } } - } - cached_sampledata->filename = FLUID_STRDUP(filename); - if (cached_sampledata->filename == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory."); - goto error_exit; - } - - cached_sampledata->modification_time = modification_time; - cached_sampledata->num_references = 1; - cached_sampledata->sampledata = loaded_sampledata; - cached_sampledata->samplesize = samplesize; - cached_sampledata->sample24data = loaded_sample24data; - cached_sampledata->sample24size = sample24size; - - cached_sampledata->next = all_cached_sampledata; - all_cached_sampledata = cached_sampledata; - - - success_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - *sampledata = loaded_sampledata; - *sample24data = loaded_sample24data; - return FLUID_OK; - - error_exit: - if (fd != NULL) { fcbs->fclose(fd); - } - - FLUID_FREE(loaded_sampledata); - FLUID_FREE(loaded_sample24data); + fd = NULL; - if (cached_sampledata != NULL) { - FLUID_FREE(cached_sampledata->filename); - } + + 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 the required permission. */ + cached_sampledata->mlock = 0; + if (try_mlock) + { + if (fluid_mlock(loaded_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 */ + if (FLUID_IS_BIG_ENDIAN) + { + unsigned char *cbuf; + unsigned char hi, lo; + unsigned int i, j; + short s; + cbuf = (unsigned char *)loaded_sampledata; + for (i = 0, j = 0; j < samplesize; i++) + { + lo = cbuf[j++]; + hi = cbuf[j++]; + s = (hi << 8) | lo; + loaded_sampledata[i] = s; + } + } + + cached_sampledata->filename = FLUID_STRDUP(filename); + if (cached_sampledata->filename == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory."); + goto error_exit; + } + + cached_sampledata->modification_time = modification_time; + cached_sampledata->num_references = 1; + cached_sampledata->sampledata = loaded_sampledata; + cached_sampledata->samplesize = samplesize; + cached_sampledata->sample24data = loaded_sample24data; + cached_sampledata->sample24size = sample24size; + + cached_sampledata->next = all_cached_sampledata; + all_cached_sampledata = cached_sampledata; + + +success_exit: + fluid_mutex_unlock(cached_sampledata_mutex); + *sampledata = loaded_sampledata; + *sample24data = loaded_sample24data; + return FLUID_OK; + +error_exit: + if (fd != NULL) + { + fcbs->fclose(fd); + } + + FLUID_FREE(loaded_sampledata); + FLUID_FREE(loaded_sample24data); + + if (cached_sampledata != NULL) + { + FLUID_FREE(cached_sampledata->filename); + } FLUID_FREE(cached_sampledata); - fluid_mutex_unlock(cached_sampledata_mutex); - *sampledata = NULL; - *sample24data = NULL; - return FLUID_FAILED; + fluid_mutex_unlock(cached_sampledata_mutex); + *sampledata = NULL; + *sample24data = NULL; + return FLUID_FAILED; } int fluid_cached_sampledata_unload(const short *sampledata) { - fluid_cached_sampledata_t* prev = NULL; - fluid_cached_sampledata_t* cached_sampledata; + fluid_cached_sampledata_t *prev = NULL; + fluid_cached_sampledata_t *cached_sampledata; - fluid_mutex_lock(cached_sampledata_mutex); - cached_sampledata = all_cached_sampledata; + fluid_mutex_lock(cached_sampledata_mutex); + cached_sampledata = all_cached_sampledata; - while (cached_sampledata != NULL) { - if (sampledata == cached_sampledata->sampledata) { - - cached_sampledata->num_references--; - - if (cached_sampledata->num_references == 0) { - if (cached_sampledata->mlock) + while (cached_sampledata != NULL) + { + if (sampledata == cached_sampledata->sampledata) { - fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize); - fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size); - } - FLUID_FREE(cached_sampledata->sampledata); - FLUID_FREE(cached_sampledata->sample24data); - FLUID_FREE(cached_sampledata->filename); - if (prev != NULL) { - prev->next = cached_sampledata->next; - } else { - all_cached_sampledata = cached_sampledata->next; + cached_sampledata->num_references--; + + if (cached_sampledata->num_references == 0) + { + if (cached_sampledata->mlock) + { + fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize); + fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size); + } + FLUID_FREE(cached_sampledata->sampledata); + FLUID_FREE(cached_sampledata->sample24data); + FLUID_FREE(cached_sampledata->filename); + + if (prev != NULL) + { + prev->next = cached_sampledata->next; + } + else + { + all_cached_sampledata = cached_sampledata->next; + } + + FLUID_FREE(cached_sampledata); + } + + goto success_exit; } - FLUID_FREE(cached_sampledata); - } - - goto success_exit; + prev = cached_sampledata; + cached_sampledata = cached_sampledata->next; } - prev = cached_sampledata; - cached_sampledata = cached_sampledata->next; - } + FLUID_LOG(FLUID_ERR, "Trying to free sampledata not found in cache."); + goto error_exit; - FLUID_LOG(FLUID_ERR, "Trying to free sampledata not found in cache."); - goto error_exit; - - success_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - return FLUID_OK; +success_exit: + fluid_mutex_unlock(cached_sampledata_mutex); + return FLUID_OK; - error_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - return FLUID_FAILED; +error_exit: + fluid_mutex_unlock(cached_sampledata_mutex); + return FLUID_FAILED; } diff --git a/src/sfloader/fluid_samplecache.h b/src/sfloader/fluid_samplecache.h index 3b3e8e7b..3fdeb8dc 100644 --- a/src/sfloader/fluid_samplecache.h +++ b/src/sfloader/fluid_samplecache.h @@ -25,10 +25,15 @@ #include "fluid_sfont.h" int fluid_cached_sampledata_load(char *filename, - unsigned int samplepos, unsigned int samplesize, short **sampledata, - unsigned int sample24pos, unsigned int sample24size, char **sample24data, - int try_mlock, const fluid_file_callbacks_t* fcbs); + unsigned int samplepos, + unsigned int samplesize, + short **sampledata, + unsigned int sample24pos, + unsigned int sample24size, + char **sample24data, + int try_mlock, + const fluid_file_callbacks_t *fcbs); int fluid_cached_sampledata_unload(const short *sampledata); -#endif /* _FLUID_SAMPLECACHE_H */ +#endif /* _FLUID_SAMPLECACHE_H */ From 870fc56d6aa12a642f6a261689feb97579ee3e7f Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 31/47] Code cleanup and formatting in fluid_samplecache --- src/sfloader/fluid_samplecache.c | 48 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index fa4e6bc0..73f7c914 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -30,9 +30,11 @@ * CACHED SAMPLEDATA LOADER */ -typedef struct _fluid_cached_sampledata_t +typedef struct _fluid_cached_sampledata_t fluid_cached_sampledata_t; + +struct _fluid_cached_sampledata_t { - struct _fluid_cached_sampledata_t *next; + fluid_cached_sampledata_t *next; char *filename; time_t modification_time; @@ -44,28 +46,17 @@ typedef struct _fluid_cached_sampledata_t char *sample24data; unsigned int sample24size; -} fluid_cached_sampledata_t; +}; + static fluid_cached_sampledata_t *all_cached_sampledata = NULL; static fluid_mutex_t cached_sampledata_mutex = FLUID_MUTEX_INIT; -static int fluid_get_file_modification_time(char *filename, time_t *modification_time) -{ -#if defined(WIN32) || defined(__OS2__) - *modification_time = 0; - return FLUID_OK; -#else - struct stat buf; - if (stat(filename, &buf) == -1) - { - return FLUID_FAILED; - } +static int fluid_get_file_modification_time(char *filename, time_t *modification_time); - *modification_time = buf.st_mtime; - return FLUID_OK; -#endif -} + +/* PUBLIC INTERFACE */ int fluid_cached_sampledata_load(char *filename, unsigned int samplepos, @@ -313,3 +304,24 @@ error_exit: fluid_mutex_unlock(cached_sampledata_mutex); return FLUID_FAILED; } + + +/* Private functions */ + +static int fluid_get_file_modification_time(char *filename, time_t *modification_time) +{ +#if defined(WIN32) || defined(__OS2__) + *modification_time = 0; + return FLUID_OK; +#else + struct stat buf; + + if (stat(filename, &buf) == -1) + { + return FLUID_FAILED; + } + + *modification_time = buf.st_mtime; + return FLUID_OK; +#endif +} From 5bc2d33bb9ea70e42dfc79cc4d07b3faf9650983 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 32/47] Differences in sample chunk sizes are not an error but simply an indication of a changed file --- src/sfloader/fluid_samplecache.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index 73f7c914..415a36ad 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -90,12 +90,7 @@ int fluid_cached_sampledata_load(char *filename, if (cached_sampledata->modification_time != modification_time) continue; if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) - { - FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont " - "(cached: %u. actual: %u)", - cached_sampledata->samplesize, samplesize); continue; - } if (try_mlock && !cached_sampledata->mlock) { From 4932b4af90561f08b888807096bb8305b33b7b39 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 33/47] Refactor sample cache loader - move sample reading to fluid_sffile - refactor sample cache to use fluid_list and separate long functions into smaller ones - include sample start and count in cache key, in preparation for lazy loading - make defsfont use new sample cache loader interface --- src/sfloader/fluid_defsfont.c | 27 ++- src/sfloader/fluid_samplecache.c | 373 ++++++++++++++----------------- src/sfloader/fluid_samplecache.h | 15 +- src/sfloader/fluid_sffile.c | 99 ++++++++ src/sfloader/fluid_sffile.h | 2 + 5 files changed, 288 insertions(+), 228 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 7e13d1fc..02e30e4d 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -286,7 +286,7 @@ int delete_fluid_defsfont(fluid_defsfont_t* sfont) } if (sfont->sampledata != NULL) { - fluid_cached_sampledata_unload(sfont->sampledata); + fluid_samplecache_unload(sfont->sampledata); } while (sfont->preset_stack_size > 0) @@ -347,8 +347,11 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f sfont->sample24size = sfdata->sample24size; /* load sample data in one block */ - if (fluid_defsfont_load_sampledata(sfont, fcbs) != FLUID_OK) + if (fluid_samplecache_load(sfdata, 0, sfdata->samplesize / 2, sfont->mlock, + &sfont->sampledata, &sfont->sample24data) == FLUID_FAILED) + { goto err_exit; + } /* Create all the sample headers */ p = sfdata->sample; @@ -443,11 +446,21 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* fcbs) { - return fluid_cached_sampledata_load(sfont->filename, - sfont->samplepos, sfont->samplesize, &sfont->sampledata, - sfont->sample24pos, sfont->sample24size, &sfont->sample24data, - sfont->mlock, - fcbs); + SFData *sfdata; + int ret; + + sfdata = fluid_sffile_load(sfont->filename, fcbs); + if (sfdata == NULL) { + FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file"); + return FLUID_FAILED; + } + + /* load sample data in one block */ + ret = fluid_samplecache_load(sfdata, 0, sfdata->samplesize / 2, sfont->mlock, + &sfont->sampledata, &sfont->sample24data); + + fluid_sffile_close (sfdata); + return ret; } /* diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index 415a36ad..48734ba0 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -21,287 +21,238 @@ * 02110-1301, USA */ +/* CACHED SAMPLE DATA LOADER + * + * This is a wrapper around fluid_sffile_read_sample_data that attempts to cache the read + * data across all FluidSynth instances in a global (process-wide) list. + */ + #include "fluid_samplecache.h" #include "fluid_sys.h" #include "fluidsynth.h" +#include "fluid_list.h" -/*************************************************************** - * - * CACHED SAMPLEDATA LOADER - */ -typedef struct _fluid_cached_sampledata_t fluid_cached_sampledata_t; +typedef struct _fluid_samplecache_entry_t fluid_samplecache_entry_t; -struct _fluid_cached_sampledata_t +struct _fluid_samplecache_entry_t { - fluid_cached_sampledata_t *next; - + /* The follwing members all form the cache key */ char *filename; time_t modification_time; + unsigned int sf_samplepos; + unsigned int sf_samplesize; + unsigned int sf_sample24pos; + unsigned int sf_sample24size; + unsigned int sample_start; + unsigned int sample_count; + /* End of cache key members */ + + short *sample_data; + char *sample_data24; + int num_references; - int mlock; - - short *sampledata; - unsigned int samplesize; - - char *sample24data; - unsigned int sample24size; + int mlocked; }; +static fluid_list_t *samplecache_list = NULL; +static fluid_mutex_t samplecache_mutex = FLUID_MUTEX_INIT; -static fluid_cached_sampledata_t *all_cached_sampledata = NULL; -static fluid_mutex_t cached_sampledata_mutex = FLUID_MUTEX_INIT; - +static fluid_samplecache_entry_t *new_samplecache_entry(SFData *sf, unsigned int sample_start, unsigned int sample_count); +static fluid_samplecache_entry_t *get_samplecache_entry(SFData *sf, unsigned int sample_start, unsigned int sample_count); +static void delete_samplecache_entry(fluid_samplecache_entry_t *entry); static int fluid_get_file_modification_time(char *filename, time_t *modification_time); /* PUBLIC INTERFACE */ -int fluid_cached_sampledata_load(char *filename, - unsigned int samplepos, - unsigned int samplesize, - short **sampledata, - unsigned int sample24pos, - unsigned int sample24size, - char **sample24data, - int try_mlock, - const fluid_file_callbacks_t *fcbs) +int fluid_samplecache_load(SFData *sf, + unsigned int sample_start, unsigned int sample_count, + int try_mlock, short **sample_data, char **sample_data24) { - fluid_file fd = NULL; - short *loaded_sampledata = NULL; - char *loaded_sample24data = NULL; - fluid_cached_sampledata_t *cached_sampledata = NULL; - time_t modification_time; + fluid_samplecache_entry_t *entry; - fluid_mutex_lock(cached_sampledata_mutex); + fluid_mutex_lock(samplecache_mutex); - if (fluid_get_file_modification_time(filename, &modification_time) == FLUID_FAILED) + entry = get_samplecache_entry(sf, sample_start, sample_count); + if (entry == NULL) { - FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); - modification_time = 0; - } - - for (cached_sampledata = all_cached_sampledata; cached_sampledata; - cached_sampledata = cached_sampledata->next) - { - if (FLUID_STRCMP(filename, cached_sampledata->filename)) - continue; - if (cached_sampledata->modification_time != modification_time) - continue; - if (cached_sampledata->samplesize != samplesize || cached_sampledata->sample24size != sample24size) - continue; - - if (try_mlock && !cached_sampledata->mlock) + entry = new_samplecache_entry(sf, sample_start, sample_count); + if (entry == NULL) { - if (fluid_mlock(cached_sampledata->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 (cached_sampledata->sample24data != NULL) - if (fluid_mlock(cached_sampledata->sample24data, sample24size) != 0) - FLUID_LOG(FLUID_WARN, - "Failed to pin the sample24 data to RAM; swapping is possible."); + return FLUID_FAILED; } - cached_sampledata->num_references++; - loaded_sampledata = cached_sampledata->sampledata; - loaded_sample24data = cached_sampledata->sample24data; - goto success_exit; + samplecache_list = fluid_list_prepend(samplecache_list, entry); } - fd = fcbs->fopen(filename); - if (fd == NULL) + if (try_mlock && !entry->mlocked) { - FLUID_LOG(FLUID_ERR, "Can't open soundfont file"); - goto error_exit; - } - if (fcbs->fseek(fd, samplepos, SEEK_SET) == FLUID_FAILED) - { - perror("error"); - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - goto error_exit; - } - - loaded_sampledata = (short *)FLUID_MALLOC(samplesize); - if (loaded_sampledata == NULL) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_exit; - } - if (fcbs->fread(loaded_sampledata, samplesize, fd) == FLUID_FAILED) - { - FLUID_LOG(FLUID_ERR, "Failed to read sample data"); - goto error_exit; - } - - if (sample24pos > 0) - { - if (fcbs->fseek(fd, sample24pos, SEEK_SET) == FLUID_FAILED) + /* Lock the memory to disable paging. It's okay if this fails. It + * probably means that the user doesn't have the required permission. */ + entry->mlocked = (fluid_mlock(entry->sample_data, entry->sample_count * 2) == 0); + if (entry->sample_data24 != NULL) { - perror("error"); - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - goto error_exit; + entry->mlocked &= (fluid_mlock(entry->sample_data24, entry->sample_count) == 0); } - loaded_sample24data = (char *)FLUID_MALLOC(sample24size); - if (loaded_sample24data == NULL) + if (!entry->mlocked) { - FLUID_LOG(FLUID_ERR, "Out of memory when allocating 24bit sample, ignoring"); - } - else if (fcbs->fread(loaded_sample24data, sample24size, fd) == FLUID_FAILED) - { - FLUID_LOG(FLUID_ERR, "Failed to read sample24 data"); - FLUID_FREE(loaded_sample24data); - loaded_sample24data = NULL; - } - } - - fcbs->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 the required permission. */ - cached_sampledata->mlock = 0; - if (try_mlock) - { - if (fluid_mlock(loaded_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 */ - if (FLUID_IS_BIG_ENDIAN) - { - unsigned char *cbuf; - unsigned char hi, lo; - unsigned int i, j; - short s; - cbuf = (unsigned char *)loaded_sampledata; - for (i = 0, j = 0; j < samplesize; i++) - { - lo = cbuf[j++]; - hi = cbuf[j++]; - s = (hi << 8) | lo; - loaded_sampledata[i] = s; } } - cached_sampledata->filename = FLUID_STRDUP(filename); - if (cached_sampledata->filename == NULL) - { - FLUID_LOG(FLUID_ERR, "Out of memory."); - goto error_exit; - } + entry->num_references++; + *sample_data = entry->sample_data; + *sample_data24 = entry->sample_data24; - cached_sampledata->modification_time = modification_time; - cached_sampledata->num_references = 1; - cached_sampledata->sampledata = loaded_sampledata; - cached_sampledata->samplesize = samplesize; - cached_sampledata->sample24data = loaded_sample24data; - cached_sampledata->sample24size = sample24size; + fluid_mutex_unlock(samplecache_mutex); - cached_sampledata->next = all_cached_sampledata; - all_cached_sampledata = cached_sampledata; - - -success_exit: - fluid_mutex_unlock(cached_sampledata_mutex); - *sampledata = loaded_sampledata; - *sample24data = loaded_sample24data; return FLUID_OK; - -error_exit: - if (fd != NULL) - { - fcbs->fclose(fd); - } - - FLUID_FREE(loaded_sampledata); - FLUID_FREE(loaded_sample24data); - - if (cached_sampledata != NULL) - { - FLUID_FREE(cached_sampledata->filename); - } - FLUID_FREE(cached_sampledata); - - fluid_mutex_unlock(cached_sampledata_mutex); - *sampledata = NULL; - *sample24data = NULL; - return FLUID_FAILED; } -int fluid_cached_sampledata_unload(const short *sampledata) +int fluid_samplecache_unload(const short *sample_data) { - fluid_cached_sampledata_t *prev = NULL; - fluid_cached_sampledata_t *cached_sampledata; + fluid_list_t *entry_list; + fluid_samplecache_entry_t *entry; - fluid_mutex_lock(cached_sampledata_mutex); - cached_sampledata = all_cached_sampledata; + fluid_mutex_lock(samplecache_mutex); - while (cached_sampledata != NULL) + entry_list = samplecache_list; + while (entry_list) { - if (sampledata == cached_sampledata->sampledata) + entry = (fluid_samplecache_entry_t *)fluid_list_get(entry_list); + + if (sample_data == entry->sample_data) { + entry->num_references--; - cached_sampledata->num_references--; - - if (cached_sampledata->num_references == 0) + if (entry->num_references == 0) { - if (cached_sampledata->mlock) + if (entry->mlocked) { - fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize); - fluid_munlock(cached_sampledata->sample24data, cached_sampledata->sample24size); - } - FLUID_FREE(cached_sampledata->sampledata); - FLUID_FREE(cached_sampledata->sample24data); - FLUID_FREE(cached_sampledata->filename); - - if (prev != NULL) - { - prev->next = cached_sampledata->next; - } - else - { - all_cached_sampledata = cached_sampledata->next; + fluid_munlock(entry->sample_data, entry->sample_count * 2); + fluid_munlock(entry->sample_data24, entry->sample_count); } - FLUID_FREE(cached_sampledata); + fluid_list_remove(samplecache_list, entry); + delete_samplecache_entry(entry); } goto success_exit; } - prev = cached_sampledata; - cached_sampledata = cached_sampledata->next; + entry_list = fluid_list_next(entry_list); } - FLUID_LOG(FLUID_ERR, "Trying to free sampledata not found in cache."); + FLUID_LOG(FLUID_ERR, "Trying to free sample data not found in cache."); goto error_exit; success_exit: - fluid_mutex_unlock(cached_sampledata_mutex); + fluid_mutex_unlock(samplecache_mutex); return FLUID_OK; error_exit: - fluid_mutex_unlock(cached_sampledata_mutex); + fluid_mutex_unlock(samplecache_mutex); return FLUID_FAILED; } /* Private functions */ +static fluid_samplecache_entry_t *new_samplecache_entry(SFData *sf, + unsigned int sample_start, + unsigned int sample_count) +{ + fluid_samplecache_entry_t *entry; + + entry = FLUID_NEW(fluid_samplecache_entry_t); + if (entry == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; + } + FLUID_MEMSET(entry, 0, sizeof(*entry)); + + entry->filename = FLUID_STRDUP(sf->fname); + if (entry->filename == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_exit; + } + + if (fluid_get_file_modification_time(entry->filename, &entry->modification_time) == FLUID_FAILED) + { + FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); + entry->modification_time = 0; + } + + entry->sf_samplepos = sf->samplepos; + entry->sf_samplesize = sf->samplesize; + entry->sf_sample24pos = sf->sample24pos; + entry->sf_sample24size = sf->sample24size; + entry->sample_start = sample_start; + entry->sample_count = sample_count; + + if (fluid_sffile_read_sample_data(sf, sample_start, sample_count, + &entry->sample_data, &entry->sample_data24) == FLUID_FAILED) + { + goto error_exit; + } + + return entry; + +error_exit: + delete_samplecache_entry(entry); + return NULL; +} + +static void delete_samplecache_entry(fluid_samplecache_entry_t *entry) +{ + fluid_return_if_fail(entry != NULL); + + FLUID_FREE(entry->filename); + FLUID_FREE(entry->sample_data); + FLUID_FREE(entry->sample_data24); + FLUID_FREE(entry); +} + +static fluid_samplecache_entry_t *get_samplecache_entry(SFData *sf, + unsigned int sample_start, + unsigned int sample_count) +{ + time_t mtime; + fluid_list_t *entry_list; + fluid_samplecache_entry_t *entry; + + if (fluid_get_file_modification_time(sf->fname, &mtime) == FLUID_FAILED) + { + FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file."); + mtime = 0; + } + + entry_list = samplecache_list; + while (entry_list) + { + entry = (fluid_samplecache_entry_t *)fluid_list_get(entry_list); + + if ((FLUID_STRCMP(sf->fname, entry->filename) == 0) && + (mtime == entry->modification_time) && + (sf->samplepos == entry->sf_samplepos) && + (sf->samplesize == entry->sf_samplesize) && + (sf->sample24pos == entry->sf_sample24pos) && + (sf->sample24size == entry->sf_sample24size) && + (sample_start == entry->sample_start) && + (sample_count == entry->sample_count)) + { + return entry; + } + + entry_list = fluid_list_next(entry_list); + } + + return NULL; +} static int fluid_get_file_modification_time(char *filename, time_t *modification_time) { diff --git a/src/sfloader/fluid_samplecache.h b/src/sfloader/fluid_samplecache.h index 3fdeb8dc..704ddba1 100644 --- a/src/sfloader/fluid_samplecache.h +++ b/src/sfloader/fluid_samplecache.h @@ -23,17 +23,12 @@ #define _FLUID_SAMPLECACHE_H #include "fluid_sfont.h" +#include "fluid_sffile.h" -int fluid_cached_sampledata_load(char *filename, - unsigned int samplepos, - unsigned int samplesize, - short **sampledata, - unsigned int sample24pos, - unsigned int sample24size, - char **sample24data, - int try_mlock, - const fluid_file_callbacks_t *fcbs); +int fluid_samplecache_load(SFData *sf, + unsigned int sample_start, unsigned int sample_count, + int try_mlock, short **data, char **data24); -int fluid_cached_sampledata_unload(const short *sampledata); +int fluid_samplecache_unload(const short *sample_data); #endif /* _FLUID_SAMPLECACHE_H */ diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index c6474367..04b52960 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -353,6 +353,105 @@ error_exit: return NULL; } +/* Load sample data from the soundfont file + * + * @param sf SFFile instance + * @param start start offset of sample data (in sample words from start of sample data chunk) + * @param count number of samples to read (in sample words) + * @param data pointer to sample data pointer, set on success + * @param data24 pointer to 24-bit sample data pointer if 24-bit data present, set on success + * + * @return FLUID_OK on success, otherwise FLUID_FAILED + */ +int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int count, + short **data, char **data24) +{ + unsigned int end; + short *loaded_data = NULL; + char *loaded_data24 = NULL; + + fluid_return_val_if_fail(count != 0, FLUID_FAILED); + + end = start + count; + + if (((start * 2) > sf->samplesize) || ((end * 2) > sf->samplesize)) + { + FLUID_LOG(FLUID_ERR, "Sample offsets exceed sample data chunk"); + goto error_exit; + } + + if (sf->sample24pos && ((start > sf->sample24size) || (end > sf->sample24size))) + { + FLUID_LOG(FLUID_ERR, "Sample offsets exceed 24-bit sample data chunk"); + goto error_exit; + } + + /* Load 16-bit sample data */ + if (sf->fcbs->fseek(sf->sffd, sf->samplepos + (start * 2), SEEK_SET) == FLUID_FAILED) + { + perror("error"); + FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); + goto error_exit; + } + + loaded_data = (short *)FLUID_MALLOC(count * 2); + if (loaded_data == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto error_exit; + } + + if (sf->fcbs->fread(loaded_data, count * 2, sf->sffd) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, "Failed to read sample data"); + goto error_exit; + } + + /* If this machine is big endian, byte swap the 16 bit samples */ + if (FLUID_IS_BIG_ENDIAN) + { + unsigned int i; + for (i = 0; i < count; i++) + { + loaded_data[i] = FLUID_LE16TOH(loaded_data[i]); + } + } + + /* Optionally load additional 8 bit sample data for 24-bit support */ + if (sf->sample24pos) + { + if (sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED) + { + perror("error"); + FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); + goto error_exit; + } + + loaded_data24 = (char *)FLUID_MALLOC(count); + if (loaded_data24 == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FLUID_FAILED; + } + + if (sf->fcbs->fread(loaded_data24, count, sf->sffd) == FLUID_FAILED) + { + FLUID_LOG(FLUID_ERR, "Failed to read 24-bit sample data"); + goto error_exit; + } + } + + *data = loaded_data; + *data24 = loaded_data24; + + return FLUID_OK; + +error_exit: + FLUID_FREE(loaded_data); + FLUID_FREE(loaded_data24); + return FLUID_FAILED; +} + /* * Close a SoundFont file and free the SFData structure. * diff --git a/src/sfloader/fluid_sffile.h b/src/sfloader/fluid_sffile.h index ac6f6651..eca67394 100644 --- a/src/sfloader/fluid_sffile.h +++ b/src/sfloader/fluid_sffile.h @@ -206,5 +206,7 @@ struct _SFShdr /* Public functions */ SFData *fluid_sffile_load(const char *fname, const fluid_file_callbacks_t *fcbs); void fluid_sffile_close(SFData *sf); +int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int count, + short **data, char **data24); #endif /* _FLUID_SFFILE_H */ From 802490761020f8eae1376c807379cce665c5e031 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 34/47] No need for fluid_sample_* functions in fluid_sfont to be public --- src/sfloader/fluid_sfont.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sfloader/fluid_sfont.h b/src/sfloader/fluid_sfont.h index 2ce3ee10..50c31bb5 100644 --- a/src/sfloader/fluid_sfont.h +++ b/src/sfloader/fluid_sfont.h @@ -24,9 +24,9 @@ #include "fluidsynth.h" -FLUIDSYNTH_API int fluid_sample_validate(fluid_sample_t *sample, unsigned int max_end); -FLUIDSYNTH_API int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int max_end); -FLUIDSYNTH_API int fluid_sample_decompress_vorbis(fluid_sample_t *sample); +int fluid_sample_validate(fluid_sample_t *sample, unsigned int max_end); +int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int max_end); +int fluid_sample_decompress_vorbis(fluid_sample_t *sample); /* * Utility macros to access soundfonts, presets, and samples From d5407742a685ac9823f5e94da2352d91603fa385 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 35/47] Always release the mutex when exiting fluid_samplecache_load And change fluid_samplecache_unload to use the same style. --- src/sfloader/fluid_samplecache.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index 48734ba0..1984ad91 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -72,6 +72,7 @@ int fluid_samplecache_load(SFData *sf, int try_mlock, short **sample_data, char **sample_data24) { fluid_samplecache_entry_t *entry; + int ret; fluid_mutex_lock(samplecache_mutex); @@ -81,7 +82,8 @@ int fluid_samplecache_load(SFData *sf, entry = new_samplecache_entry(sf, sample_start, sample_count); if (entry == NULL) { - return FLUID_FAILED; + ret = FLUID_FAILED; + goto unlock_exit; } samplecache_list = fluid_list_prepend(samplecache_list, entry); @@ -106,16 +108,18 @@ int fluid_samplecache_load(SFData *sf, entry->num_references++; *sample_data = entry->sample_data; *sample_data24 = entry->sample_data24; + ret = FLUID_OK; +unlock_exit: fluid_mutex_unlock(samplecache_mutex); - - return FLUID_OK; + return ret; } int fluid_samplecache_unload(const short *sample_data) { fluid_list_t *entry_list; fluid_samplecache_entry_t *entry; + int ret; fluid_mutex_lock(samplecache_mutex); @@ -140,22 +144,19 @@ int fluid_samplecache_unload(const short *sample_data) delete_samplecache_entry(entry); } - goto success_exit; + ret = FLUID_OK; + goto unlock_exit; } entry_list = fluid_list_next(entry_list); } FLUID_LOG(FLUID_ERR, "Trying to free sample data not found in cache."); - goto error_exit; + ret = FLUID_FAILED; -success_exit: +unlock_exit: fluid_mutex_unlock(samplecache_mutex); - return FLUID_OK; - -error_exit: - fluid_mutex_unlock(samplecache_mutex); - return FLUID_FAILED; + return ret; } From 29296b0e207428ea299645dcd98fe60cde006fd2 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 36/47] Ensure that sample_data memory is unlocked even if sample_data_24 mlock fails --- src/sfloader/fluid_samplecache.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index 1984ad91..b86f4368 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -93,15 +93,22 @@ int fluid_samplecache_load(SFData *sf, { /* Lock the memory to disable paging. It's okay if this fails. It * probably means that the user doesn't have the required permission. */ - entry->mlocked = (fluid_mlock(entry->sample_data, entry->sample_count * 2) == 0); - if (entry->sample_data24 != NULL) + if (fluid_mlock(entry->sample_data, entry->sample_count * 2) == 0) { - entry->mlocked &= (fluid_mlock(entry->sample_data24, entry->sample_count) == 0); - } + if (entry->sample_data24 != NULL) + { + entry->mlocked = (fluid_mlock(entry->sample_data24, entry->sample_count) == 0); + } + else + { + entry->mlocked = TRUE; + } - if (!entry->mlocked) - { - FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible."); + if (!entry->mlocked) + { + fluid_munlock(entry->sample_data, entry->sample_count * 2); + FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible."); + } } } @@ -137,7 +144,10 @@ int fluid_samplecache_unload(const short *sample_data) if (entry->mlocked) { fluid_munlock(entry->sample_data, entry->sample_count * 2); - fluid_munlock(entry->sample_data24, entry->sample_count); + if (entry->sample_data24 != NULL) + { + fluid_munlock(entry->sample_data24, entry->sample_count); + } } fluid_list_remove(samplecache_list, entry); From c7e579aa75353f4fa5e7b857b48c904a3df382e3 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 37/47] Remove redundant error messages --- src/sfloader/fluid_sffile.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 04b52960..6dad5c90 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -389,7 +389,6 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c /* Load 16-bit sample data */ if (sf->fcbs->fseek(sf->sffd, sf->samplepos + (start * 2), SEEK_SET) == FLUID_FAILED) { - perror("error"); FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); goto error_exit; } @@ -422,7 +421,6 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c { if (sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED) { - perror("error"); FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); goto error_exit; } From e8717e5b40e2f3a68e84bc4ec4c933c8ac624fb6 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 38/47] Remove explicit cast of FLUID_MALLOC return value --- src/sfloader/fluid_sffile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 6dad5c90..6d47dba4 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -393,7 +393,7 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c goto error_exit; } - loaded_data = (short *)FLUID_MALLOC(count * 2); + loaded_data = FLUID_MALLOC(count * 2); if (loaded_data == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); @@ -425,7 +425,7 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c goto error_exit; } - loaded_data24 = (char *)FLUID_MALLOC(count); + loaded_data24 = FLUID_MALLOC(count); if (loaded_data24 == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); From 352bdef5331f6c0562bf95de73ac0e7c644a5aed Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 39/47] Properly free memory on error --- src/sfloader/fluid_sffile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 6d47dba4..6d6d428c 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -429,7 +429,7 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c if (loaded_data24 == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; + goto error_exit; } if (sf->fcbs->fread(loaded_data24, count, sf->sffd) == FLUID_FAILED) From 312459eaf14d37f9331a27751a87972605789637 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 40/47] Treat failures while loading 24-bit sample data as not fatal --- src/sfloader/fluid_sffile.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 6d6d428c..e1c9cb00 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -380,12 +380,6 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c goto error_exit; } - if (sf->sample24pos && ((start > sf->sample24size) || (end > sf->sample24size))) - { - FLUID_LOG(FLUID_ERR, "Sample offsets exceed 24-bit sample data chunk"); - goto error_exit; - } - /* Load 16-bit sample data */ if (sf->fcbs->fseek(sf->sffd, sf->samplepos + (start * 2), SEEK_SET) == FLUID_FAILED) { @@ -416,34 +410,49 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c } } - /* Optionally load additional 8 bit sample data for 24-bit support */ + *data = loaded_data; + + /* Optionally load additional 8 bit sample data for 24-bit support. Any failures while loading + * the 24-bit sample data will be logged as errors but won't prevent the sample reading to + * fail, as sound output is still possible with the 16-bit sample data. */ if (sf->sample24pos) { + if ((start > sf->sample24size) || (end > sf->sample24size)) + { + FLUID_LOG(FLUID_ERR, "Sample offsets exceed 24-bit sample data chunk"); + goto error24_exit; + } + if (sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, "Failed to seek position in data file"); - goto error_exit; + FLUID_LOG(FLUID_ERR, "Failed to seek position for 24-bit sample data in data file"); + goto error24_exit; } loaded_data24 = FLUID_MALLOC(count); if (loaded_data24 == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_exit; + FLUID_LOG(FLUID_ERR, "Out of memory reading 24-bit sample data"); + goto error24_exit; } if (sf->fcbs->fread(loaded_data24, count, sf->sffd) == FLUID_FAILED) { FLUID_LOG(FLUID_ERR, "Failed to read 24-bit sample data"); - goto error_exit; + goto error24_exit; } } - *data = loaded_data; *data24 = loaded_data24; return FLUID_OK; +error24_exit: + FLUID_LOG(FLUID_WARN, "Ignoring 24-bit sample data, sound quality might suffer"); + FLUID_FREE(loaded_data24); + *data24 = NULL; + return FLUID_OK; + error_exit: FLUID_FREE(loaded_data); FLUID_FREE(loaded_data24); From cf04a4ff739ed56276f5122c8bc143289510acdb Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 41/47] Use FLUID_ARRAY instead of FLUID_MALLOC for sample buffers --- src/sfloader/fluid_sffile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index e1c9cb00..337e1ca2 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -387,14 +387,14 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c goto error_exit; } - loaded_data = FLUID_MALLOC(count * 2); + loaded_data = FLUID_ARRAY(short, count); if (loaded_data == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); goto error_exit; } - if (sf->fcbs->fread(loaded_data, count * 2, sf->sffd) == FLUID_FAILED) + if (sf->fcbs->fread(loaded_data, count * sizeof(short), sf->sffd) == FLUID_FAILED) { FLUID_LOG(FLUID_ERR, "Failed to read sample data"); goto error_exit; @@ -429,7 +429,7 @@ int fluid_sffile_read_sample_data(SFData *sf, unsigned int start, unsigned int c goto error24_exit; } - loaded_data24 = FLUID_MALLOC(count); + loaded_data24 = FLUID_ARRAY(char, count); if (loaded_data24 == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory reading 24-bit sample data"); From 109e8990b8bebd9236ae375e9b362e9cde89e15f Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 42/47] Use FLUID_STRDUP instead of manual allocate and copy for strings in defsfont loader --- src/sfloader/fluid_defsfont.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 02e30e4d..535a589e 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -325,12 +325,11 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f fluid_sample_t* sample; fluid_defpreset_t* preset = NULL; - sfont->filename = FLUID_MALLOC(1 + FLUID_STRLEN(file)); + sfont->filename = FLUID_STRDUP(file); if (sfont->filename == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return FLUID_FAILED; } - FLUID_STRCPY(sfont->filename, file); /* The actual loading is done in the sfont and sffile files */ sfdata = fluid_sffile_load(file, fcbs); @@ -908,7 +907,6 @@ fluid_preset_zone_next(fluid_preset_zone_t* preset) fluid_preset_zone_t* new_fluid_preset_zone(char *name) { - int size; fluid_preset_zone_t* zone = NULL; zone = FLUID_NEW(fluid_preset_zone_t); if (zone == NULL) { @@ -916,14 +914,12 @@ new_fluid_preset_zone(char *name) return NULL; } zone->next = NULL; - size = 1 + FLUID_STRLEN(name); - zone->name = FLUID_MALLOC(size); + zone->name = FLUID_STRDUP(name); if (zone->name == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); FLUID_FREE(zone); return NULL; } - FLUID_STRCPY(zone->name, name); zone->inst = NULL; zone->range.keylo = 0; zone->range.keyhi = 128; @@ -1299,7 +1295,6 @@ fluid_inst_get_global_zone(fluid_inst_t* inst) fluid_inst_zone_t* new_fluid_inst_zone(char* name) { - int size; fluid_inst_zone_t* zone = NULL; zone = FLUID_NEW(fluid_inst_zone_t); if (zone == NULL) { @@ -1307,14 +1302,12 @@ new_fluid_inst_zone(char* name) return NULL; } zone->next = NULL; - size = 1 + FLUID_STRLEN(name); - zone->name = FLUID_MALLOC(size); + zone->name = FLUID_STRDUP(name); if (zone->name == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); FLUID_FREE(zone); return NULL; } - FLUID_STRCPY(zone->name, name); zone->sample = NULL; zone->range.keylo = 0; zone->range.keyhi = 128; From d1c620f9989223e912347da543a7a1d8d857b28b Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 43/47] Use fluid_list_get to access list entry data --- src/sfloader/fluid_defsfont.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 535a589e..e7ec0f23 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -355,7 +355,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f /* Create all the sample headers */ p = sfdata->sample; while (p != NULL) { - sfsample = (SFSample *) p->data; + sfsample = (SFSample *)fluid_list_get(p); sample = new_fluid_sample(); if (sample == NULL) goto err_exit; @@ -374,7 +374,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f /* Load all the presets */ p = sfdata->preset; while (p != NULL) { - sfpreset = (SFPreset *) p->data; + sfpreset = (SFPreset *)fluid_list_get(p); preset = new_fluid_defpreset(sfont); if (preset == NULL) goto err_exit; @@ -832,7 +832,7 @@ fluid_defpreset_import_sfont(fluid_defpreset_t* preset, p = sfpreset->zone; count = 0; while (p != NULL) { - sfzone = (SFZone *) p->data; + sfzone = (SFZone *)fluid_list_get(p); FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%d", preset->name, count); zone = new_fluid_preset_zone(zone_name); if (zone == NULL) { @@ -968,7 +968,7 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_ SFGen* sfgen; int count; for (count = 0, r = sfzone->gen; r != NULL; count++) { - sfgen = (SFGen *) r->data; + sfgen = (SFGen *)fluid_list_get(r); switch (sfgen->id) { case GEN_KEYRANGE: zone->range.keylo = sfgen->amount.range.lo; @@ -1007,7 +1007,7 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_ /* Import the modulators (only SF2.1 and higher) */ for (count = 0, r = sfzone->mod; r != NULL; count++) { - SFMod* mod_src = (SFMod *)r->data; + SFMod* mod_src = (SFMod *)fluid_list_get(r); fluid_mod_t * mod_dest = new_fluid_mod(); int type; @@ -1224,7 +1224,7 @@ fluid_inst_import_sfont(fluid_preset_zone_t* zonePZ, fluid_inst_t* inst, count = 0; while (p != NULL) { - sfzone = (SFZone *) p->data; + sfzone = (SFZone *)fluid_list_get(p); FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%d", inst->name, count); zone = new_fluid_inst_zone(zone_name); @@ -1364,7 +1364,7 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t int count; for (count = 0, r = sfzone->gen; r != NULL; count++) { - sfgen = (SFGen *) r->data; + sfgen = (SFGen *)fluid_list_get(r); switch (sfgen->id) { case GEN_KEYRANGE: zone->range.keylo = sfgen->amount.range.lo; @@ -1408,7 +1408,7 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t /* Import the modulators (only SF2.1 and higher) */ for (count = 0, r = sfzone->mod; r != NULL; count++) { - SFMod* mod_src = (SFMod *) r->data; + SFMod* mod_src = (SFMod *)fluid_list_get(r); int type; fluid_mod_t* mod_dest; From 7e36bcf05868011a03ac55bcc85ce3a073976c2f Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 44/47] Rename parameters and variables to better reflect their contents / use As fluid_defsfont contains code that deals with fluid_sfont_t and fluid_defsfont_t, fluid_preset_t and fluid_defpreset_t, it sometimes gets very confusion to know which type is currently being accessed by "sfont" or "preset". Also clarify some preset zone / inst zone ambiguities. --- src/sfloader/fluid_defsfont.c | 354 +++++++++++++++++----------------- src/sfloader/fluid_defsfont.h | 58 +++--- 2 files changed, 206 insertions(+), 206 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index e7ec0f23..1744916e 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -173,11 +173,11 @@ int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* pr void fluid_defpreset_preset_delete(fluid_preset_t* preset) { fluid_defpreset_t* defpreset = fluid_preset_get_data(preset); - fluid_defsfont_t* sfont = defpreset ? defpreset->sfont : NULL; + fluid_defsfont_t* defsfont = defpreset ? defpreset->defsfont : NULL; - if (sfont && sfont->preset_stack_size < sfont->preset_stack_capacity) { - sfont->preset_stack[sfont->preset_stack_size] = preset; - sfont->preset_stack_size++; + if (defsfont && defsfont->preset_stack_size < defsfont->preset_stack_capacity) { + defsfont->preset_stack[defsfont->preset_stack_size] = preset; + defsfont->preset_stack_size++; } else delete_fluid_preset(preset); @@ -215,118 +215,118 @@ int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, */ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings) { - fluid_defsfont_t* sfont; + fluid_defsfont_t* defsfont; int i; - sfont = FLUID_NEW(fluid_defsfont_t); - if (sfont == NULL) { + defsfont = FLUID_NEW(fluid_defsfont_t); + if (defsfont == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } - FLUID_MEMSET(sfont, 0, sizeof(*sfont)); + FLUID_MEMSET(defsfont, 0, sizeof(*defsfont)); - fluid_settings_getint(settings, "synth.lock-memory", &sfont->mlock); + fluid_settings_getint(settings, "synth.lock-memory", &defsfont->mlock); /* Initialise preset cache, so we don't have to call malloc on program changes. Usually, we have at most one preset per channel plus one temporarily used, so optimise for that case. */ - fluid_settings_getint(settings, "synth.midi-channels", &sfont->preset_stack_capacity); - sfont->preset_stack_capacity++; + fluid_settings_getint(settings, "synth.midi-channels", &defsfont->preset_stack_capacity); + defsfont->preset_stack_capacity++; - sfont->preset_stack = FLUID_ARRAY(fluid_preset_t*, sfont->preset_stack_capacity); - if (!sfont->preset_stack) { + defsfont->preset_stack = FLUID_ARRAY(fluid_preset_t*, defsfont->preset_stack_capacity); + if (!defsfont->preset_stack) { FLUID_LOG(FLUID_ERR, "Out of memory"); - FLUID_FREE(sfont); + FLUID_FREE(defsfont); return NULL; } - for (i = 0; i < sfont->preset_stack_capacity; i++) { - sfont->preset_stack[i] = FLUID_NEW(fluid_preset_t); - if (!sfont->preset_stack[i]) { + for (i = 0; i < defsfont->preset_stack_capacity; i++) { + defsfont->preset_stack[i] = FLUID_NEW(fluid_preset_t); + if (!defsfont->preset_stack[i]) { FLUID_LOG(FLUID_ERR, "Out of memory"); - delete_fluid_defsfont(sfont); + delete_fluid_defsfont(defsfont); return NULL; } - sfont->preset_stack_size++; + defsfont->preset_stack_size++; } - return sfont; + return defsfont; } /* * delete_fluid_defsfont */ -int delete_fluid_defsfont(fluid_defsfont_t* sfont) +int delete_fluid_defsfont(fluid_defsfont_t* defsfont) { fluid_list_t *list; - fluid_defpreset_t* preset; + fluid_defpreset_t* defpreset; fluid_sample_t* sample; - fluid_return_val_if_fail(sfont != NULL, FLUID_OK); + fluid_return_val_if_fail(defsfont != NULL, FLUID_OK); /* Check that no samples are currently used */ - for (list = sfont->sample; list; list = fluid_list_next(list)) { + for (list = defsfont->sample; list; list = fluid_list_next(list)) { sample = (fluid_sample_t*) fluid_list_get(list); if (sample->refcount != 0) { return FLUID_FAILED; } } - if (sfont->filename != NULL) { - FLUID_FREE(sfont->filename); + if (defsfont->filename != NULL) { + FLUID_FREE(defsfont->filename); } - for (list = sfont->sample; list; list = fluid_list_next(list)) { + for (list = defsfont->sample; list; list = fluid_list_next(list)) { delete_fluid_sample((fluid_sample_t*) fluid_list_get(list)); } - if (sfont->sample) { - delete_fluid_list(sfont->sample); + if (defsfont->sample) { + delete_fluid_list(defsfont->sample); } - if (sfont->sampledata != NULL) { - fluid_samplecache_unload(sfont->sampledata); + if (defsfont->sampledata != NULL) { + fluid_samplecache_unload(defsfont->sampledata); } - while (sfont->preset_stack_size > 0) - FLUID_FREE(sfont->preset_stack[--sfont->preset_stack_size]); - FLUID_FREE(sfont->preset_stack); + while (defsfont->preset_stack_size > 0) + FLUID_FREE(defsfont->preset_stack[--defsfont->preset_stack_size]); + FLUID_FREE(defsfont->preset_stack); - preset = sfont->preset; - while (preset != NULL) { - sfont->preset = preset->next; - delete_fluid_defpreset(preset); - preset = sfont->preset; + defpreset = defsfont->preset; + while (defpreset != NULL) { + defsfont->preset = defpreset->next; + delete_fluid_defpreset(defpreset); + defpreset = defsfont->preset; } - FLUID_FREE(sfont); + FLUID_FREE(defsfont); return FLUID_OK; } /* * fluid_defsfont_get_name */ -const char* fluid_defsfont_get_name(fluid_defsfont_t* sfont) +const char* fluid_defsfont_get_name(fluid_defsfont_t* defsfont) { - return sfont->filename; + return defsfont->filename; } /* * fluid_defsfont_load */ -int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* fcbs, const char* file) +int fluid_defsfont_load(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* fcbs, const char* file) { SFData* sfdata; fluid_list_t *p; SFPreset* sfpreset; SFSample* sfsample; fluid_sample_t* sample; - fluid_defpreset_t* preset = NULL; + fluid_defpreset_t* defpreset = NULL; - sfont->filename = FLUID_STRDUP(file); - if (sfont->filename == NULL) { + defsfont->filename = FLUID_STRDUP(file); + if (defsfont->filename == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return FLUID_FAILED; } @@ -340,14 +340,14 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f /* Keep track of the position and size of the sample data because it's loaded separately (and might be unoaded/reloaded in future) */ - sfont->samplepos = sfdata->samplepos; - sfont->samplesize = sfdata->samplesize; - sfont->sample24pos = sfdata->sample24pos; - sfont->sample24size = sfdata->sample24size; + defsfont->samplepos = sfdata->samplepos; + defsfont->samplesize = sfdata->samplesize; + defsfont->sample24pos = sfdata->sample24pos; + defsfont->sample24size = sfdata->sample24size; /* load sample data in one block */ - if (fluid_samplecache_load(sfdata, 0, sfdata->samplesize / 2, sfont->mlock, - &sfont->sampledata, &sfont->sample24data) == FLUID_FAILED) + if (fluid_samplecache_load(sfdata, 0, sfdata->samplesize / 2, defsfont->mlock, + &defsfont->sampledata, &defsfont->sample24data) == FLUID_FAILED) { goto err_exit; } @@ -360,13 +360,13 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f sample = new_fluid_sample(); if (sample == NULL) goto err_exit; - if (fluid_sample_import_sfont(sample, sfsample, sfont) != FLUID_OK) + if (fluid_sample_import_sfont(sample, sfsample, defsfont) != FLUID_OK) goto err_exit; /* Store reference to FluidSynth sample in SFSample for later IZone fixups */ sfsample->fluid_sample = sample; - fluid_defsfont_add_sample(sfont, sample); + fluid_defsfont_add_sample(defsfont, sample); fluid_voice_optimize_sample(sample); p = fluid_list_next(p); } @@ -375,13 +375,13 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f p = sfdata->preset; while (p != NULL) { sfpreset = (SFPreset *)fluid_list_get(p); - preset = new_fluid_defpreset(sfont); - if (preset == NULL) goto err_exit; + defpreset = new_fluid_defpreset(defsfont); + if (defpreset == NULL) goto err_exit; - if (fluid_defpreset_import_sfont(preset, sfpreset, sfont) != FLUID_OK) + if (fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont) != FLUID_OK) goto err_exit; - fluid_defsfont_add_preset(sfont, preset); + fluid_defsfont_add_preset(defsfont, defpreset); p = fluid_list_next(p); } fluid_sffile_close (sfdata); @@ -390,7 +390,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* f err_exit: fluid_sffile_close (sfdata); - delete_fluid_defpreset(preset); + delete_fluid_defpreset(defpreset); return FLUID_FAILED; } @@ -398,9 +398,9 @@ err_exit: * * Add a sample to the SoundFont */ -int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample) +int fluid_defsfont_add_sample(fluid_defsfont_t* defsfont, fluid_sample_t* sample) { - sfont->sample = fluid_list_append(sfont->sample, sample); + defsfont->sample = fluid_list_append(defsfont->sample, sample); return FLUID_OK; } @@ -408,33 +408,33 @@ int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample) * * Add a preset to the SoundFont */ -int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset) +int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* defpreset) { fluid_defpreset_t *cur, *prev; - if (sfont->preset == NULL) { - preset->next = NULL; - sfont->preset = preset; + if (defsfont->preset == NULL) { + defpreset->next = NULL; + defsfont->preset = defpreset; } else { /* sort them as we go along. very basic sorting trick. */ - cur = sfont->preset; + cur = defsfont->preset; prev = NULL; while (cur != NULL) { - if ((preset->bank < cur->bank) - || ((preset->bank == cur->bank) && (preset->num < cur->num))) { + if ((defpreset->bank < cur->bank) + || ((defpreset->bank == cur->bank) && (defpreset->num < cur->num))) { if (prev == NULL) { - preset->next = cur; - sfont->preset = preset; + defpreset->next = cur; + defsfont->preset = defpreset; } else { - preset->next = cur; - prev->next = preset; + defpreset->next = cur; + prev->next = defpreset; } return FLUID_OK; } prev = cur; cur = cur->next; } - preset->next = NULL; - prev->next = preset; + defpreset->next = NULL; + prev->next = defpreset; } return FLUID_OK; } @@ -443,20 +443,20 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset * fluid_defsfont_load_sampledata */ int -fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* fcbs) +fluid_defsfont_load_sampledata(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* fcbs) { SFData *sfdata; int ret; - sfdata = fluid_sffile_load(sfont->filename, fcbs); + sfdata = fluid_sffile_load(defsfont->filename, fcbs); if (sfdata == NULL) { FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file"); return FLUID_FAILED; } /* load sample data in one block */ - ret = fluid_samplecache_load(sfdata, 0, sfdata->samplesize / 2, sfont->mlock, - &sfont->sampledata, &sfont->sample24data); + ret = fluid_samplecache_load(sfdata, 0, sfdata->samplesize / 2, defsfont->mlock, + &defsfont->sampledata, &defsfont->sample24data); fluid_sffile_close (sfdata); return ret; @@ -465,14 +465,14 @@ fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, const fluid_file_callbac /* * fluid_defsfont_get_preset */ -fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int num) +fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int num) { - fluid_defpreset_t* preset = sfont->preset; - while (preset != NULL) { - if ((preset->bank == bank) && ((preset->num == num))) { - return preset; + fluid_defpreset_t* defpreset = defsfont->preset; + while (defpreset != NULL) { + if ((defpreset->bank == bank) && ((defpreset->num == num))) { + return defpreset; } - preset = preset->next; + defpreset = defpreset->next; } return NULL; } @@ -480,22 +480,22 @@ fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned i /* * fluid_defsfont_iteration_start */ -void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont) +void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont) { - sfont->iter_cur = sfont->preset; + defsfont->iter_cur = defsfont->preset; } /* * fluid_defsfont_iteration_next */ -int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset) +int fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont, fluid_preset_t* preset) { - if (sfont->iter_cur == NULL) { + if (defsfont->iter_cur == NULL) { return 0; } - preset->data = (void*) sfont->iter_cur; - sfont->iter_cur = fluid_defpreset_next(sfont->iter_cur); + preset->data = (void*) defsfont->iter_cur; + defsfont->iter_cur = fluid_defpreset_next(defsfont->iter_cur); return 1; } @@ -508,70 +508,70 @@ int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* prese * new_fluid_defpreset */ fluid_defpreset_t* -new_fluid_defpreset(fluid_defsfont_t* sfont) +new_fluid_defpreset(fluid_defsfont_t* defsfont) { - fluid_defpreset_t* preset = FLUID_NEW(fluid_defpreset_t); - if (preset == NULL) { + fluid_defpreset_t* defpreset = FLUID_NEW(fluid_defpreset_t); + if (defpreset == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } - preset->next = NULL; - preset->sfont = sfont; - preset->name[0] = 0; - preset->bank = 0; - preset->num = 0; - preset->global_zone = NULL; - preset->zone = NULL; - return preset; + defpreset->next = NULL; + defpreset->defsfont = defsfont; + defpreset->name[0] = 0; + defpreset->bank = 0; + defpreset->num = 0; + defpreset->global_zone = NULL; + defpreset->zone = NULL; + return defpreset; } /* * delete_fluid_defpreset */ void -delete_fluid_defpreset(fluid_defpreset_t* preset) +delete_fluid_defpreset(fluid_defpreset_t* defpreset) { fluid_preset_zone_t* zone; - fluid_return_if_fail(preset != NULL); + fluid_return_if_fail(defpreset != NULL); - delete_fluid_preset_zone(preset->global_zone); - preset->global_zone = NULL; + delete_fluid_preset_zone(defpreset->global_zone); + defpreset->global_zone = NULL; - zone = preset->zone; + zone = defpreset->zone; while (zone != NULL) { - preset->zone = zone->next; + defpreset->zone = zone->next; delete_fluid_preset_zone(zone); - zone = preset->zone; + zone = defpreset->zone; } - FLUID_FREE(preset); + FLUID_FREE(defpreset); } int -fluid_defpreset_get_banknum(fluid_defpreset_t* preset) +fluid_defpreset_get_banknum(fluid_defpreset_t* defpreset) { - return preset->bank; + return defpreset->bank; } int -fluid_defpreset_get_num(fluid_defpreset_t* preset) +fluid_defpreset_get_num(fluid_defpreset_t* defpreset) { - return preset->num; + return defpreset->num; } const char* -fluid_defpreset_get_name(fluid_defpreset_t* preset) +fluid_defpreset_get_name(fluid_defpreset_t* defpreset) { - return preset->name; + return defpreset->name; } /* * fluid_defpreset_next */ fluid_defpreset_t* -fluid_defpreset_next(fluid_defpreset_t* preset) +fluid_defpreset_next(fluid_defpreset_t* defpreset) { - return preset->next; + return defpreset->next; } @@ -579,7 +579,7 @@ fluid_defpreset_next(fluid_defpreset_t* preset) * fluid_defpreset_noteon */ int -fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel) +fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int chan, int key, int vel) { fluid_preset_zone_t *preset_zone, *global_preset_zone; fluid_inst_t* inst; @@ -591,10 +591,10 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan int mod_list_count; int i; - global_preset_zone = fluid_defpreset_get_global_zone(preset); + global_preset_zone = fluid_defpreset_get_global_zone(defpreset); /* run thru all the zones of this preset */ - preset_zone = fluid_defpreset_get_zone(preset); + preset_zone = fluid_defpreset_get_zone(defpreset); while (preset_zone != NULL) { /* check if the note falls into the key and velocity range of this @@ -803,9 +803,9 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan * fluid_defpreset_set_global_zone */ int -fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone) +fluid_defpreset_set_global_zone(fluid_defpreset_t* defpreset, fluid_preset_zone_t* zone) { - preset->global_zone = zone; + defpreset->global_zone = zone; return FLUID_OK; } @@ -813,9 +813,9 @@ fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* * fluid_defpreset_import_sfont */ int -fluid_defpreset_import_sfont(fluid_defpreset_t* preset, +fluid_defpreset_import_sfont(fluid_defpreset_t* defpreset, SFPreset* sfpreset, - fluid_defsfont_t* sfont) + fluid_defsfont_t* defsfont) { fluid_list_t *p; SFZone* sfzone; @@ -823,28 +823,28 @@ fluid_defpreset_import_sfont(fluid_defpreset_t* preset, int count; char zone_name[256]; if (FLUID_STRLEN(sfpreset->name) > 0) { - FLUID_STRCPY(preset->name, sfpreset->name); + FLUID_STRCPY(defpreset->name, sfpreset->name); } else { - FLUID_SNPRINTF(preset->name, sizeof(preset->name), "Bank%d,Pre%d", sfpreset->bank, sfpreset->prenum); + FLUID_SNPRINTF(defpreset->name, sizeof(defpreset->name), "Bank%d,Pre%d", sfpreset->bank, sfpreset->prenum); } - preset->bank = sfpreset->bank; - preset->num = sfpreset->prenum; + defpreset->bank = sfpreset->bank; + defpreset->num = sfpreset->prenum; p = sfpreset->zone; count = 0; while (p != NULL) { sfzone = (SFZone *)fluid_list_get(p); - FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%d", preset->name, count); + FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%d", defpreset->name, count); zone = new_fluid_preset_zone(zone_name); if (zone == NULL) { return FLUID_FAILED; } - if (fluid_preset_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) { + if (fluid_preset_zone_import_sfont(zone, sfzone, defsfont) != FLUID_OK) { delete_fluid_preset_zone(zone); return FLUID_FAILED; } if ((count == 0) && (fluid_preset_zone_get_inst(zone) == NULL)) { - fluid_defpreset_set_global_zone(preset, zone); - } else if (fluid_defpreset_add_zone(preset, zone) != FLUID_OK) { + fluid_defpreset_set_global_zone(defpreset, zone); + } else if (fluid_defpreset_add_zone(defpreset, zone) != FLUID_OK) { return FLUID_FAILED; } p = fluid_list_next(p); @@ -857,14 +857,14 @@ fluid_defpreset_import_sfont(fluid_defpreset_t* preset, * fluid_defpreset_add_zone */ int -fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone) +fluid_defpreset_add_zone(fluid_defpreset_t* defpreset, fluid_preset_zone_t* zone) { - if (preset->zone == NULL) { + if (defpreset->zone == NULL) { zone->next = NULL; - preset->zone = zone; + defpreset->zone = zone; } else { - zone->next = preset->zone; - preset->zone = zone; + zone->next = defpreset->zone; + defpreset->zone = zone; } return FLUID_OK; } @@ -873,18 +873,18 @@ fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone) * fluid_defpreset_get_zone */ fluid_preset_zone_t* -fluid_defpreset_get_zone(fluid_defpreset_t* preset) +fluid_defpreset_get_zone(fluid_defpreset_t* defpreset) { - return preset->zone; + return defpreset->zone; } /* * fluid_defpreset_get_global_zone */ fluid_preset_zone_t* -fluid_defpreset_get_global_zone(fluid_defpreset_t* preset) +fluid_defpreset_get_global_zone(fluid_defpreset_t* defpreset) { - return preset->global_zone; + return defpreset->global_zone; } /*************************************************************** @@ -896,9 +896,9 @@ fluid_defpreset_get_global_zone(fluid_defpreset_t* preset) * fluid_preset_zone_next */ fluid_preset_zone_t* -fluid_preset_zone_next(fluid_preset_zone_t* preset) +fluid_preset_zone_next(fluid_preset_zone_t* zone) { - return preset->next; + return zone->next; } /* @@ -962,7 +962,7 @@ delete_fluid_preset_zone(fluid_preset_zone_t* zone) * fluid_preset_zone_import_sfont */ int -fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont) +fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* defsfont) { fluid_list_t *r; SFGen* sfgen; @@ -999,7 +999,7 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_ return FLUID_FAILED; } if (fluid_inst_import_sfont(zone, zone->inst, - (SFInst *) sfzone->instsamp->data, sfont) != FLUID_OK) { + (SFInst *) sfzone->instsamp->data, defsfont) != FLUID_OK) { return FLUID_FAILED; } } @@ -1205,12 +1205,12 @@ fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone) * fluid_inst_import_sfont */ int -fluid_inst_import_sfont(fluid_preset_zone_t* zonePZ, fluid_inst_t* inst, - SFInst *sfinst, fluid_defsfont_t* sfont) +fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst, + SFInst *sfinst, fluid_defsfont_t* defsfont) { fluid_list_t *p; SFZone* sfzone; - fluid_inst_zone_t* zone; + fluid_inst_zone_t* inst_zone; char zone_name[256]; int count; @@ -1227,20 +1227,20 @@ fluid_inst_import_sfont(fluid_preset_zone_t* zonePZ, fluid_inst_t* inst, sfzone = (SFZone *)fluid_list_get(p); FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%d", inst->name, count); - zone = new_fluid_inst_zone(zone_name); - if (zone == NULL) { + inst_zone = new_fluid_inst_zone(zone_name); + if (inst_zone == NULL) { return FLUID_FAILED; } - if (fluid_inst_zone_import_sfont(zonePZ,zone, sfzone, sfont) != FLUID_OK) { - delete_fluid_inst_zone(zone); + if (fluid_inst_zone_import_sfont(preset_zone, inst_zone, sfzone, defsfont) != FLUID_OK) { + delete_fluid_inst_zone(inst_zone); return FLUID_FAILED; } - if ((count == 0) && (fluid_inst_zone_get_sample(zone) == NULL)) { - fluid_inst_set_global_zone(inst, zone); + if ((count == 0) && (fluid_inst_zone_get_sample(inst_zone) == NULL)) { + fluid_inst_set_global_zone(inst, inst_zone); - } else if (fluid_inst_add_zone(inst, zone) != FLUID_OK) { + } else if (fluid_inst_add_zone(inst, inst_zone) != FLUID_OK) { return FLUID_FAILED; } @@ -1356,8 +1356,8 @@ fluid_inst_zone_next(fluid_inst_zone_t* zone) * fluid_inst_zone_import_sfont */ int -fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t* zone, - SFZone *sfzone, fluid_defsfont_t* sfont) +fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t* inst_zone, + SFZone *sfzone, fluid_defsfont_t* defsfont) { fluid_list_t *r; SFGen* sfgen; @@ -1367,35 +1367,35 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t sfgen = (SFGen *)fluid_list_get(r); switch (sfgen->id) { case GEN_KEYRANGE: - zone->range.keylo = sfgen->amount.range.lo; - zone->range.keyhi = sfgen->amount.range.hi; + inst_zone->range.keylo = sfgen->amount.range.lo; + inst_zone->range.keyhi = sfgen->amount.range.hi; break; case GEN_VELRANGE: - zone->range.vello = sfgen->amount.range.lo; - zone->range.velhi = sfgen->amount.range.hi; + inst_zone->range.vello = sfgen->amount.range.lo; + inst_zone->range.velhi = sfgen->amount.range.hi; break; case GEN_ATTENUATION: /* EMU8k/10k hardware applies a scale factor to initial attenuation generator values set at * preset and instrument level */ - zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword * EMU_ATTENUATION_FACTOR; - zone->gen[sfgen->id].flags = GEN_SET; + inst_zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword * EMU_ATTENUATION_FACTOR; + inst_zone->gen[sfgen->id].flags = GEN_SET; break; default: /* FIXME: some generators have an unsigned word amount value but i don't know which ones */ - zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword; - zone->gen[sfgen->id].flags = GEN_SET; + inst_zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword; + inst_zone->gen[sfgen->id].flags = GEN_SET; break; } r = fluid_list_next(r); } /* adjust instrument zone keyrange to integrate preset zone keyrange */ - if (preset_zone->range.keylo > zone->range.keylo) zone->range.keylo = preset_zone->range.keylo; - if (preset_zone->range.keyhi < zone->range.keyhi) zone->range.keyhi = preset_zone->range.keyhi; + if (preset_zone->range.keylo > inst_zone->range.keylo) inst_zone->range.keylo = preset_zone->range.keylo; + if (preset_zone->range.keyhi < inst_zone->range.keyhi) inst_zone->range.keyhi = preset_zone->range.keyhi; /* adjust instrument zone to integrate preset zone velrange */ - if (preset_zone->range.vello > zone->range.vello) zone->range.vello = preset_zone->range.vello; - if (preset_zone->range.velhi < zone->range.velhi) zone->range.velhi = preset_zone->range.velhi; + if (preset_zone->range.vello > inst_zone->range.vello) inst_zone->range.vello = preset_zone->range.vello; + if (preset_zone->range.velhi < inst_zone->range.velhi) inst_zone->range.velhi = preset_zone->range.velhi; /* FIXME */ /* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */ @@ -1404,7 +1404,7 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t /* fixup sample pointer */ if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) - zone->sample = ((SFSample *)(sfzone->instsamp->data))->fluid_sample; + inst_zone->sample = ((SFSample *)(sfzone->instsamp->data))->fluid_sample; /* Import the modulators (only SF2.1 and higher) */ for (count = 0, r = sfzone->mod; r != NULL; count++) { @@ -1521,9 +1521,9 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t * The order of modulators will make a difference, at least in an instrument context: * The second modulator overwrites the first one, if they only differ in amount. */ if (count == 0){ - zone->mod=mod_dest; + inst_zone->mod=mod_dest; } else { - fluid_mod_t * last_mod=zone->mod; + fluid_mod_t * last_mod=inst_zone->mod; /* Find the end of the list */ while (last_mod->next != NULL){ last_mod=last_mod->next; @@ -1579,11 +1579,11 @@ fluid_sample_in_rom(fluid_sample_t* sample) * fluid_sample_import_sfont */ int -fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont) +fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* defsfont) { FLUID_STRCPY(sample->name, sfsample->name); - sample->data = sfont->sampledata; - sample->data24 = sfont->sample24data; + sample->data = defsfont->sampledata; + sample->data24 = defsfont->sample24data; sample->start = sfsample->start; sample->end = (sfsample->end > 0) ? sfsample->end - 1 : 0; /* marks last sample, contrary to SF spec. */ sample->loopstart = sfsample->loopstart; @@ -1593,7 +1593,7 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs sample->pitchadj = sfsample->pitchadj; sample->sampletype = sfsample->sampletype; - if (fluid_sample_validate(sample, sfont->samplesize) == FLUID_FAILED) + if (fluid_sample_validate(sample, defsfont->samplesize) == FLUID_FAILED) { return FLUID_OK; } @@ -1604,7 +1604,7 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs return FLUID_FAILED; } - fluid_sample_sanitize_loop(sample, sfont->samplesize); + fluid_sample_sanitize_loop(sample, defsfont->samplesize); return FLUID_OK; } diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 1c7a5868..0a3c59f7 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -116,15 +116,15 @@ struct _fluid_defsfont_t 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 fluid_file_callbacks_t* file_callbacks, const char* file); -const char* fluid_defsfont_get_name(fluid_defsfont_t* sfont); -fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int prenum); -void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont); -int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset); -int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, const fluid_file_callbacks_t* file_callbacks); -int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample); -int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset); +int delete_fluid_defsfont(fluid_defsfont_t* defsfont); +int fluid_defsfont_load(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* file_callbacks, const char* file); +const char* fluid_defsfont_get_name(fluid_defsfont_t* defsfont); +fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int prenum); +void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont); +int fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont, fluid_preset_t* preset); +int fluid_defsfont_load_sampledata(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* file_callbacks); +int fluid_defsfont_add_sample(fluid_defsfont_t* defsfont, fluid_sample_t* sample); +int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* defpreset); /* @@ -133,7 +133,7 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset struct _fluid_defpreset_t { fluid_defpreset_t* next; - fluid_defsfont_t* sfont; /* the soundfont this preset belongs to */ + fluid_defsfont_t* defsfont; /* the soundfont this preset belongs to */ char name[21]; /* the name of the preset */ unsigned int bank; /* the bank number */ unsigned int num; /* the preset number */ @@ -141,18 +141,18 @@ struct _fluid_defpreset_t fluid_preset_zone_t* zone; /* the chained list of preset zones */ }; -fluid_defpreset_t* new_fluid_defpreset(fluid_defsfont_t* sfont); -void delete_fluid_defpreset(fluid_defpreset_t* preset); -fluid_defpreset_t* fluid_defpreset_next(fluid_defpreset_t* preset); -int fluid_defpreset_import_sfont(fluid_defpreset_t* preset, SFPreset* sfpreset, fluid_defsfont_t* sfont); -int fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone); -int fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone); -fluid_preset_zone_t* fluid_defpreset_get_zone(fluid_defpreset_t* preset); -fluid_preset_zone_t* fluid_defpreset_get_global_zone(fluid_defpreset_t* preset); -int fluid_defpreset_get_banknum(fluid_defpreset_t* preset); -int fluid_defpreset_get_num(fluid_defpreset_t* preset); -const char* fluid_defpreset_get_name(fluid_defpreset_t* preset); -int fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); +fluid_defpreset_t* new_fluid_defpreset(fluid_defsfont_t* defsfont); +void delete_fluid_defpreset(fluid_defpreset_t* defpreset); +fluid_defpreset_t* fluid_defpreset_next(fluid_defpreset_t* defpreset); +int fluid_defpreset_import_sfont(fluid_defpreset_t* defpreset, SFPreset* sfpreset, fluid_defsfont_t* defsfont); +int fluid_defpreset_set_global_zone(fluid_defpreset_t* defpreset, fluid_preset_zone_t* zone); +int fluid_defpreset_add_zone(fluid_defpreset_t* defpreset, fluid_preset_zone_t* zone); +fluid_preset_zone_t* fluid_defpreset_get_zone(fluid_defpreset_t* defpreset); +fluid_preset_zone_t* fluid_defpreset_get_global_zone(fluid_defpreset_t* defpreset); +int fluid_defpreset_get_banknum(fluid_defpreset_t* defpreset); +int fluid_defpreset_get_num(fluid_defpreset_t* defpreset); +const char* fluid_defpreset_get_name(fluid_defpreset_t* defpreset); +int fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int chan, int key, int vel); /* * fluid_preset_zone @@ -169,8 +169,8 @@ struct _fluid_preset_zone_t fluid_preset_zone_t* new_fluid_preset_zone(char* name); void delete_fluid_preset_zone(fluid_preset_zone_t* zone); -fluid_preset_zone_t* fluid_preset_zone_next(fluid_preset_zone_t* preset); -int fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone* sfzone, fluid_defsfont_t* sfont); +fluid_preset_zone_t* fluid_preset_zone_next(fluid_preset_zone_t* zone); +int fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone* sfzone, fluid_defsfont_t* defssfont); fluid_inst_t* fluid_preset_zone_get_inst(fluid_preset_zone_t* zone); /* @@ -184,8 +184,8 @@ struct _fluid_inst_t }; fluid_inst_t* new_fluid_inst(void); -int fluid_inst_import_sfont(fluid_preset_zone_t* zonePZ, fluid_inst_t* inst, - SFInst *sfinst, fluid_defsfont_t* sfont); +int fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst, + SFInst *sfinst, fluid_defsfont_t* defsfont); void delete_fluid_inst(fluid_inst_t* inst); int fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone); int fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone); @@ -209,13 +209,13 @@ struct _fluid_inst_zone_t fluid_inst_zone_t* new_fluid_inst_zone(char* name); void delete_fluid_inst_zone(fluid_inst_zone_t* zone); fluid_inst_zone_t* fluid_inst_zone_next(fluid_inst_zone_t* zone); -int fluid_inst_zone_import_sfont(fluid_preset_zone_t* zonePZ, - fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont); +int fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, + fluid_inst_zone_t* inst_zone, SFZone *sfzone, fluid_defsfont_t* defsfont); fluid_sample_t* fluid_inst_zone_get_sample(fluid_inst_zone_t* zone); -int fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont); +int fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* defsfont); int fluid_sample_in_rom(fluid_sample_t* sample); From f8bc376392e14eb7b98951bbdd5ee735785c6764 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Wed, 4 Apr 2018 11:03:47 +0200 Subject: [PATCH 45/47] Use glib's g_stat to get file modification time --- src/sfloader/fluid_samplecache.c | 9 ++------- src/utils/fluid_sys.h | 6 ++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index b86f4368..adb7f7a9 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -267,18 +267,13 @@ static fluid_samplecache_entry_t *get_samplecache_entry(SFData *sf, static int fluid_get_file_modification_time(char *filename, time_t *modification_time) { -#if defined(WIN32) || defined(__OS2__) - *modification_time = 0; - return FLUID_OK; -#else - struct stat buf; + fluid_stat_buf_t buf; - if (stat(filename, &buf) == -1) + if (fluid_stat(filename, &buf)) { return FLUID_FAILED; } *modification_time = buf.st_mtime; return FLUID_OK; -#endif } diff --git a/src/utils/fluid_sys.h b/src/utils/fluid_sys.h index 13c0b7ff..787f5992 100644 --- a/src/utils/fluid_sys.h +++ b/src/utils/fluid_sys.h @@ -42,6 +42,8 @@ #include #endif +#include + /** * Macro used for safely accessing a message from a GError and using a default * message if it is NULL. @@ -355,6 +357,10 @@ void fluid_socket_close(fluid_socket_t sock); fluid_istream_t fluid_socket_get_istream(fluid_socket_t sock); fluid_ostream_t fluid_socket_get_ostream(fluid_socket_t sock); +/* File access */ +typedef GStatBuf fluid_stat_buf_t; +#define fluid_stat(_filename, _statbuf) g_stat((_filename), (_statbuf)) + /* Profiling */ #if WITH_PROFILING From 362a3f2a81ebdd5a6704d219c475d006ee0d7db9 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Thu, 5 Apr 2018 19:20:17 +0200 Subject: [PATCH 46/47] Fix bug in removing element from samplecache_list --- src/sfloader/fluid_samplecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfloader/fluid_samplecache.c b/src/sfloader/fluid_samplecache.c index adb7f7a9..e1af5bb8 100644 --- a/src/sfloader/fluid_samplecache.c +++ b/src/sfloader/fluid_samplecache.c @@ -150,7 +150,7 @@ int fluid_samplecache_unload(const short *sample_data) } } - fluid_list_remove(samplecache_list, entry); + samplecache_list = fluid_list_remove(samplecache_list, entry); delete_samplecache_entry(entry); } From 9c1f3bd53ee1fda06e1a72ac8e8cc71b8b56377b Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Thu, 5 Apr 2018 19:20:47 +0200 Subject: [PATCH 47/47] Return FLUID_OK instead if TRUE to be consistent with other return values --- src/sfloader/fluid_sfont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfloader/fluid_sfont.c b/src/sfloader/fluid_sfont.c index 69e53ec1..73b1efc1 100644 --- a/src/sfloader/fluid_sfont.c +++ b/src/sfloader/fluid_sfont.c @@ -586,7 +586,7 @@ int fluid_sample_validate(fluid_sample_t *sample, unsigned int buffer_size) return FLUID_FAILED; } - return TRUE; + return FLUID_OK; } /* Check the sample loop pointers and optionally convert them to something