mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-14 00:20:41 +00:00
add fluid_file_callbacks struct to fluid_defsfont
to perform file operations through callbacks
This commit is contained in:
parent
4178bbdb72
commit
1e65ba1a49
4 changed files with 244 additions and 186 deletions
|
@ -77,6 +77,9 @@ enum {
|
||||||
struct _fluid_sfloader_t {
|
struct _fluid_sfloader_t {
|
||||||
void* data; /**< User defined data pointer */
|
void* data; /**< User defined data pointer */
|
||||||
|
|
||||||
|
/** File operation callbacks to allow custom loading, such as from memory */
|
||||||
|
fluid_file_callbacks_t* file_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The free method should free the memory allocated for the loader in
|
* The free method should free the memory allocated for the loader in
|
||||||
* addition to any private data.
|
* addition to any private data.
|
||||||
|
@ -95,7 +98,24 @@ struct _fluid_sfloader_t {
|
||||||
fluid_sfont_t* (*load)(fluid_sfloader_t* loader, const char* filename);
|
fluid_sfont_t* (*load)(fluid_sfloader_t* loader, const char* filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
struct _fluid_file_callbacks_t {
|
||||||
|
/** Accepts UTF-8 encoding, returns file handle */
|
||||||
|
void * (* fopen )(const char *);
|
||||||
|
|
||||||
|
/** Reads to specified buffer, returns count of size bytes read */
|
||||||
|
size_t (* fread )(void *, size_t size, size_t count, void * handle);
|
||||||
|
|
||||||
|
/** Returns zero on success, -1 on error */
|
||||||
|
int (* fseek )(void * handle, long, int);
|
||||||
|
|
||||||
|
/** Returns zero on success, -1 on error */
|
||||||
|
int (* fclose)(void * handle);
|
||||||
|
|
||||||
|
/** Returns current file offset */
|
||||||
|
long (* ftell )(void * handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
* Virtual SoundFont instance structure.
|
* Virtual SoundFont instance structure.
|
||||||
*/
|
*/
|
||||||
struct _fluid_sfont_t {
|
struct _fluid_sfont_t {
|
||||||
|
|
|
@ -58,7 +58,7 @@ typedef struct _fluid_ramsfont_t fluid_ramsfont_t; /**< RAM SoundFo
|
||||||
typedef struct _fluid_rampreset_t fluid_rampreset_t; /**< RAM SoundFont preset */
|
typedef struct _fluid_rampreset_t fluid_rampreset_t; /**< RAM SoundFont preset */
|
||||||
typedef struct _fluid_cmd_handler_t fluid_cmd_handler_t; /**< Shell Command Handler */
|
typedef struct _fluid_cmd_handler_t fluid_cmd_handler_t; /**< Shell Command Handler */
|
||||||
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t; /**< LADSPA effects instance */
|
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t; /**< LADSPA effects instance */
|
||||||
|
typedef struct _fluid_file_callbacks_t fluid_file_callbacks_t; /**< Callback struct to perform custom file loading of soundfonts */
|
||||||
|
|
||||||
typedef int fluid_istream_t; /**< Input stream descriptor */
|
typedef int fluid_istream_t; /**< Input stream descriptor */
|
||||||
typedef int fluid_ostream_t; /**< Output stream descriptor */
|
typedef int fluid_ostream_t; /**< Output stream descriptor */
|
||||||
|
|
|
@ -35,6 +35,42 @@
|
||||||
* SFONT LOADER
|
* SFONT LOADER
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void * default_fopen(const char * path)
|
||||||
|
{
|
||||||
|
return fopen(path, "rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t default_fread(void * buffer, size_t size, size_t count, void * handle)
|
||||||
|
{
|
||||||
|
return fread(buffer, size, count, (FILE *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int default_fseek(void * handle, long offset, int whence)
|
||||||
|
{
|
||||||
|
return fseek((FILE *)handle, offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
int default_fclose(void * handle)
|
||||||
|
{
|
||||||
|
fclose((FILE *)handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long default_ftell(void * handle)
|
||||||
|
{
|
||||||
|
return ftell((FILE *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fluid_file_callbacks_t def_file_callbacks =
|
||||||
|
{
|
||||||
|
default_fopen,
|
||||||
|
default_fread,
|
||||||
|
default_fseek,
|
||||||
|
default_fclose,
|
||||||
|
default_ftell
|
||||||
|
};
|
||||||
|
|
||||||
fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
|
fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
|
||||||
{
|
{
|
||||||
fluid_sfloader_t* loader;
|
fluid_sfloader_t* loader;
|
||||||
|
@ -46,6 +82,7 @@ fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
loader->data = settings;
|
loader->data = settings;
|
||||||
|
loader->file_callbacks = &def_file_callbacks;
|
||||||
loader->free = delete_fluid_defsfloader;
|
loader->free = delete_fluid_defsfloader;
|
||||||
loader->load = fluid_defsfloader_load;
|
loader->load = fluid_defsfloader_load;
|
||||||
|
|
||||||
|
@ -71,7 +108,7 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fluid_defsfont_load(defsfont, filename) == FLUID_FAILED) {
|
if (fluid_defsfont_load(defsfont, loader->file_callbacks, filename) == FLUID_FAILED) {
|
||||||
delete_fluid_defsfont(defsfont);
|
delete_fluid_defsfont(defsfont);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -543,7 +580,7 @@ const char* fluid_defsfont_get_name(fluid_defsfont_t* sfont)
|
||||||
/*
|
/*
|
||||||
* fluid_defsfont_load
|
* fluid_defsfont_load
|
||||||
*/
|
*/
|
||||||
int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
|
int fluid_defsfont_load(fluid_defsfont_t* sfont, fluid_file_callbacks_t* fcbs, const char* file)
|
||||||
{
|
{
|
||||||
SFData* sfdata;
|
SFData* sfdata;
|
||||||
fluid_list_t *p;
|
fluid_list_t *p;
|
||||||
|
@ -560,7 +597,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
|
||||||
FLUID_STRCPY(sfont->filename, file);
|
FLUID_STRCPY(sfont->filename, file);
|
||||||
|
|
||||||
/* The actual loading is done in the sfont and sffile files */
|
/* The actual loading is done in the sfont and sffile files */
|
||||||
sfdata = sfload_file(file);
|
sfdata = sfload_file(file, fcbs);
|
||||||
if (sfdata == NULL) {
|
if (sfdata == NULL) {
|
||||||
FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file");
|
FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file");
|
||||||
return FLUID_FAILED;
|
return FLUID_FAILED;
|
||||||
|
@ -572,7 +609,7 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
|
||||||
sfont->samplesize = sfdata->samplesize;
|
sfont->samplesize = sfdata->samplesize;
|
||||||
|
|
||||||
/* load sample data in one block */
|
/* load sample data in one block */
|
||||||
if (fluid_defsfont_load_sampledata(sfont) != FLUID_OK)
|
if (fluid_defsfont_load_sampledata(sfont, fcbs) != FLUID_OK)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
||||||
/* Create all the sample headers */
|
/* Create all the sample headers */
|
||||||
|
@ -607,12 +644,12 @@ int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
|
||||||
fluid_defsfont_add_preset(sfont, preset);
|
fluid_defsfont_add_preset(sfont, preset);
|
||||||
p = fluid_list_next(p);
|
p = fluid_list_next(p);
|
||||||
}
|
}
|
||||||
sfont_close (sfdata);
|
sfont_close (sfdata, fcbs);
|
||||||
|
|
||||||
return FLUID_OK;
|
return FLUID_OK;
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
sfont_close (sfdata);
|
sfont_close (sfdata, fcbs);
|
||||||
delete_fluid_defpreset(preset);
|
delete_fluid_defpreset(preset);
|
||||||
return FLUID_FAILED;
|
return FLUID_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -666,7 +703,7 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset
|
||||||
* fluid_defsfont_load_sampledata
|
* fluid_defsfont_load_sampledata
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont)
|
fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos,
|
return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos,
|
||||||
sfont->samplesize, &sfont->sampledata, sfont->mlock);
|
sfont->samplesize, &sfont->sampledata, sfont->mlock);
|
||||||
|
@ -2021,49 +2058,50 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs
|
||||||
equivalent to the matching ID list in memory regardless of LE/BE machine
|
equivalent to the matching ID list in memory regardless of LE/BE machine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define READCHUNK(var,fd) do { \
|
#define READCHUNK(var,fd, fcbs) do { \
|
||||||
if (!safe_fread(var, 8, fd)) \
|
if (!safe_fread(var, 8, fd, fcbs)) \
|
||||||
|
<<<<<<< HEAD:src/sfloader/fluid_defsfont.c
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \
|
((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READD(var,fd) do { \
|
#define READD(var,fd, fcbs) do { \
|
||||||
uint32_t _temp; \
|
uint32_t _temp; \
|
||||||
if (!safe_fread(&_temp, 4, fd)) \
|
if (!safe_fread(&_temp, 4, fd, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
var = FLUID_LE32TOH(_temp); \
|
var = FLUID_LE32TOH(_temp); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READW(var,fd) do { \
|
#define READW(var,fd, fcbs) do { \
|
||||||
uint16_t _temp; \
|
uint16_t _temp; \
|
||||||
if (!safe_fread(&_temp, 2, fd)) \
|
if (!safe_fread(&_temp, 2, fd, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
var = FLUID_LE16TOH(_temp); \
|
var = FLUID_LE16TOH(_temp); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READID(var,fd) do { \
|
#define READID(var,fd, fcbs) do { \
|
||||||
if (!safe_fread(var, 4, fd)) \
|
if (!safe_fread(var, 4, fd, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READSTR(var,fd) do { \
|
#define READSTR(var,fd, fcbs) do { \
|
||||||
if (!safe_fread(var, 20, fd)) \
|
if (!safe_fread(var, 20, fd, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
(*var)[20] = '\0'; \
|
(*var)[20] = '\0'; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READB(var,fd) do { \
|
#define READB(var,fd, fcbs) do { \
|
||||||
if (!safe_fread(&var, 1, fd)) \
|
if (!safe_fread(&var, 1, fd, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define FSKIP(size,fd) do { \
|
#define FSKIP(size,fd, fcbs) do { \
|
||||||
if (!safe_fseek(fd, size, SEEK_CUR)) \
|
if (!safe_fseek(fd, size, SEEK_CUR, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define FSKIPW(fd) do { \
|
#define FSKIPW(fd, fcbs) do { \
|
||||||
if (!safe_fseek(fd, 2, SEEK_CUR)) \
|
if (!safe_fseek(fd, 2, SEEK_CUR, fcbs)) \
|
||||||
return(FAIL); \
|
return(FAIL); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
@ -2076,22 +2114,22 @@ fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defs
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
static int chunkid (unsigned int id);
|
static int chunkid (unsigned int id);
|
||||||
static int load_body (unsigned int size, SFData * sf, FILE * fd);
|
static int load_body (unsigned int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int read_listchunk (SFChunk * chunk, FILE * fd);
|
static int read_listchunk (SFChunk * chunk, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int process_info (int size, SFData * sf, FILE * fd);
|
static int process_info (int size, SFData * sf, void* fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int process_sdta (unsigned int size, SFData * sf, FILE * fd);
|
static int process_sdta (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
|
static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
|
||||||
int * size, FILE * fd);
|
int * size, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int process_pdta (int size, SFData * sf, FILE * fd);
|
static int process_pdta (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_phdr (int size, SFData * sf, FILE * fd);
|
static int load_phdr (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_pbag (int size, SFData * sf, FILE * fd);
|
static int load_pbag (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_pmod (int size, SFData * sf, FILE * fd);
|
static int load_pmod (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_pgen (int size, SFData * sf, FILE * fd);
|
static int load_pgen (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_ihdr (int size, SFData * sf, FILE * fd);
|
static int load_ihdr (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_ibag (int size, SFData * sf, FILE * fd);
|
static int load_ibag (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_imod (int size, SFData * sf, FILE * fd);
|
static int load_imod (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_igen (int size, SFData * sf, FILE * fd);
|
static int load_igen (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int load_shdr (unsigned int size, SFData * sf, FILE * fd);
|
static int load_shdr (unsigned int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
static int fixup_pgen (SFData * sf);
|
static int fixup_pgen (SFData * sf);
|
||||||
static int fixup_igen (SFData * sf);
|
static int fixup_igen (SFData * sf);
|
||||||
static int fixup_sample (SFData * sf);
|
static int fixup_sample (SFData * sf);
|
||||||
|
@ -2119,14 +2157,14 @@ chunkid (unsigned int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
SFData *
|
SFData *
|
||||||
sfload_file (const char * fname)
|
sfload_file (const char * fname, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
SFData *sf = NULL;
|
SFData *sf = NULL;
|
||||||
FILE *fd;
|
void *fd;
|
||||||
int fsize = 0;
|
int fsize = 0;
|
||||||
int err = FALSE;
|
int err = FALSE;
|
||||||
|
|
||||||
if (!(fd = fopen (fname, "rb")))
|
if (!(fd = fcbs->fopen (fname)))
|
||||||
{
|
{
|
||||||
FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname);
|
FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -2147,12 +2185,12 @@ sfload_file (const char * fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get size of file */
|
/* get size of file */
|
||||||
if (!err && fseek (fd, 0L, SEEK_END) == -1)
|
if (!err && fcbs->fseek (fd, 0L, SEEK_END) == -1)
|
||||||
{ /* seek to end of file */
|
{ /* seek to end of file */
|
||||||
err = TRUE;
|
err = TRUE;
|
||||||
FLUID_LOG (FLUID_ERR, _("Seek to end of file failed"));
|
FLUID_LOG (FLUID_ERR, _("Seek to end of file failed"));
|
||||||
}
|
}
|
||||||
if (!err && (fsize = ftell (fd)) == -1)
|
if (!err && (fsize = fcbs->ftell (fd)) == -1)
|
||||||
{ /* position = size */
|
{ /* position = size */
|
||||||
err = TRUE;
|
err = TRUE;
|
||||||
FLUID_LOG (FLUID_ERR, _("Get end of file position failed"));
|
FLUID_LOG (FLUID_ERR, _("Get end of file position failed"));
|
||||||
|
@ -2160,13 +2198,13 @@ sfload_file (const char * fname)
|
||||||
if (!err)
|
if (!err)
|
||||||
rewind (fd);
|
rewind (fd);
|
||||||
|
|
||||||
if (!err && !load_body (fsize, sf, fd))
|
if (!err && !load_body (fsize, sf, fd, fcbs))
|
||||||
err = TRUE; /* load the sfont */
|
err = TRUE; /* load the sfont */
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
if (sf)
|
if (sf)
|
||||||
sfont_close (sf);
|
sfont_close (sf, fcbs);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2174,17 +2212,17 @@ sfload_file (const char * fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
load_body (unsigned int size, SFData * sf, FILE * fd)
|
load_body (unsigned int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
SFChunk chunk;
|
SFChunk chunk;
|
||||||
|
|
||||||
READCHUNK (&chunk, fd); /* load RIFF chunk */
|
READCHUNK (&chunk, fd, fcbs); /* load RIFF chunk */
|
||||||
if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */
|
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 (FAIL);
|
return (FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
READID (&chunk.id, fd); /* load file ID */
|
READID (&chunk.id, fd, fcbs); /* load file ID */
|
||||||
if (chunkid (chunk.id) != SFBK_ID) { /* error if not SFBK_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 (FAIL);
|
return (FAIL);
|
||||||
|
@ -2196,28 +2234,28 @@ load_body (unsigned int size, SFData * sf, FILE * fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process INFO block */
|
/* Process INFO block */
|
||||||
if (!read_listchunk (&chunk, fd))
|
if (!read_listchunk (&chunk, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (chunkid (chunk.id) != INFO_ID)
|
if (chunkid (chunk.id) != INFO_ID)
|
||||||
return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk")));
|
return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk")));
|
||||||
if (!process_info (chunk.size, sf, fd))
|
if (!process_info (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
/* Process sample chunk */
|
/* Process sample chunk */
|
||||||
if (!read_listchunk (&chunk, fd))
|
if (!read_listchunk (&chunk, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (chunkid (chunk.id) != SDTA_ID)
|
if (chunkid (chunk.id) != SDTA_ID)
|
||||||
return (gerr (ErrCorr,
|
return (gerr (ErrCorr,
|
||||||
_("Invalid ID found when expecting SAMPLE chunk")));
|
_("Invalid ID found when expecting SAMPLE chunk")));
|
||||||
if (!process_sdta (chunk.size, sf, fd))
|
if (!process_sdta (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
/* process HYDRA chunk */
|
/* process HYDRA chunk */
|
||||||
if (!read_listchunk (&chunk, fd))
|
if (!read_listchunk (&chunk, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (chunkid (chunk.id) != PDTA_ID)
|
if (chunkid (chunk.id) != PDTA_ID)
|
||||||
return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk")));
|
return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk")));
|
||||||
if (!process_pdta (chunk.size, sf, fd))
|
if (!process_pdta (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!fixup_pgen (sf))
|
if (!fixup_pgen (sf))
|
||||||
|
@ -2235,18 +2273,18 @@ load_body (unsigned int size, SFData * sf, FILE * fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_listchunk (SFChunk * chunk, FILE * fd)
|
read_listchunk (SFChunk * chunk, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
READCHUNK (chunk, fd); /* read list chunk */
|
READCHUNK (chunk, fd, fcbs); /* read list chunk */
|
||||||
if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */
|
if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */
|
||||||
return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse")));
|
return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse")));
|
||||||
READID (&chunk->id, fd); /* read id string */
|
READID (&chunk->id, fd, fcbs); /* read id string */
|
||||||
chunk->size -= 4;
|
chunk->size -= 4;
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_info (int size, SFData * sf, FILE * fd)
|
process_info (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
SFChunk chunk;
|
SFChunk chunk;
|
||||||
unsigned char id;
|
unsigned char id;
|
||||||
|
@ -2255,7 +2293,7 @@ process_info (int size, SFData * sf, FILE * fd)
|
||||||
|
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
READCHUNK (&chunk, fd);
|
READCHUNK (&chunk, fd, fcbs);
|
||||||
size -= 8;
|
size -= 8;
|
||||||
|
|
||||||
id = chunkid (chunk.id);
|
id = chunkid (chunk.id);
|
||||||
|
@ -2266,9 +2304,9 @@ process_info (int size, SFData * sf, FILE * fd)
|
||||||
return (gerr (ErrCorr,
|
return (gerr (ErrCorr,
|
||||||
_("Sound font version info chunk has invalid size")));
|
_("Sound font version info chunk has invalid size")));
|
||||||
|
|
||||||
READW (ver, fd);
|
READW (ver, fd, fcbs);
|
||||||
sf->version.major = ver;
|
sf->version.major = ver;
|
||||||
READW (ver, fd);
|
READW (ver, fd, fcbs);
|
||||||
sf->version.minor = ver;
|
sf->version.minor = ver;
|
||||||
|
|
||||||
if (sf->version.major < 2) {
|
if (sf->version.major < 2) {
|
||||||
|
@ -2305,9 +2343,9 @@ process_info (int size, SFData * sf, FILE * fd)
|
||||||
return (gerr (ErrCorr,
|
return (gerr (ErrCorr,
|
||||||
_("ROM version info chunk has invalid size")));
|
_("ROM version info chunk has invalid size")));
|
||||||
|
|
||||||
READW (ver, fd);
|
READW (ver, fd, fcbs);
|
||||||
sf->romver.major = ver;
|
sf->romver.major = ver;
|
||||||
READW (ver, fd);
|
READW (ver, fd, fcbs);
|
||||||
sf->romver.minor = ver;
|
sf->romver.minor = ver;
|
||||||
}
|
}
|
||||||
else if (id != UNKN_ID)
|
else if (id != UNKN_ID)
|
||||||
|
@ -2329,7 +2367,7 @@ process_info (int size, SFData * sf, FILE * fd)
|
||||||
sf->info = fluid_list_append (sf->info, item);
|
sf->info = fluid_list_append (sf->info, item);
|
||||||
|
|
||||||
*(unsigned char *) item = id;
|
*(unsigned char *) item = id;
|
||||||
if (!safe_fread (&item[1], chunk.size, fd))
|
if (!safe_fread (&item[1], chunk.size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
/* force terminate info item (don't forget uint8 info ID) */
|
/* force terminate info item (don't forget uint8 info ID) */
|
||||||
|
@ -2347,7 +2385,7 @@ process_info (int size, SFData * sf, FILE * fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_sdta (unsigned int size, SFData * sf, FILE * fd)
|
process_sdta (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
SFChunk chunk;
|
SFChunk chunk;
|
||||||
|
|
||||||
|
@ -2355,7 +2393,7 @@ process_sdta (unsigned int size, SFData * sf, FILE * fd)
|
||||||
return (OK); /* no sample data? */
|
return (OK); /* no sample data? */
|
||||||
|
|
||||||
/* read sub chunk */
|
/* read sub chunk */
|
||||||
READCHUNK (&chunk, fd);
|
READCHUNK (&chunk, fd, fcbs);
|
||||||
size -= 8;
|
size -= 8;
|
||||||
|
|
||||||
if (chunkid (chunk.id) != SMPL_ID)
|
if (chunkid (chunk.id) != SMPL_ID)
|
||||||
|
@ -2369,27 +2407,27 @@ process_sdta (unsigned int size, SFData * sf, FILE * fd)
|
||||||
return (gerr (ErrCorr, _("SDTA chunk size mismatch")));
|
return (gerr (ErrCorr, _("SDTA chunk size mismatch")));
|
||||||
|
|
||||||
/* sample data follows */
|
/* sample data follows */
|
||||||
sf->samplepos = ftell (fd);
|
sf->samplepos = fcbs->ftell (fd);
|
||||||
|
|
||||||
/* used in fixup_sample() to check validity of sample headers */
|
/* used in fixup_sample() to check validity of sample headers */
|
||||||
sdtachunk_size = chunk.size;
|
sdtachunk_size = chunk.size;
|
||||||
sf->samplesize = chunk.size;
|
sf->samplesize = chunk.size;
|
||||||
|
|
||||||
FSKIP (size, fd);
|
FSKIP (chunk.size, fd, fcbs);
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
|
pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
|
||||||
int * size, FILE * fd)
|
int * size, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
const char *expstr;
|
const char *expstr;
|
||||||
|
|
||||||
expstr = CHNKIDSTR (expid); /* in case we need it */
|
expstr = CHNKIDSTR (expid); /* in case we need it */
|
||||||
|
|
||||||
READCHUNK (chunk, fd);
|
READCHUNK (chunk, fd, fcbs);
|
||||||
*size -= 8;
|
*size -= 8;
|
||||||
|
|
||||||
if ((id = chunkid (chunk->id)) != expid)
|
if ((id = chunkid (chunk->id)) != expid)
|
||||||
|
@ -2407,53 +2445,53 @@ pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_pdta (int size, SFData * sf, FILE * fd)
|
process_pdta (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
SFChunk chunk;
|
SFChunk chunk;
|
||||||
|
|
||||||
if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd))
|
if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_phdr (chunk.size, sf, fd))
|
if (!load_phdr (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd))
|
if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_pbag (chunk.size, sf, fd))
|
if (!load_pbag (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd))
|
if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_pmod (chunk.size, sf, fd))
|
if (!load_pmod (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd))
|
if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_pgen (chunk.size, sf, fd))
|
if (!load_pgen (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd))
|
if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_ihdr (chunk.size, sf, fd))
|
if (!load_ihdr (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd))
|
if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_ibag (chunk.size, sf, fd))
|
if (!load_ibag (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd))
|
if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_imod (chunk.size, sf, fd))
|
if (!load_imod (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd))
|
if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_igen (chunk.size, sf, fd))
|
if (!load_igen (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd))
|
if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
if (!load_shdr (chunk.size, sf, fd))
|
if (!load_shdr (chunk.size, sf, fd, fcbs))
|
||||||
return (FAIL);
|
return (FAIL);
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
|
@ -2461,7 +2499,7 @@ process_pdta (int size, SFData * sf, FILE * fd)
|
||||||
|
|
||||||
/* preset header loader */
|
/* preset header loader */
|
||||||
static int
|
static int
|
||||||
load_phdr (int size, SFData * sf, FILE * fd)
|
load_phdr (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
int i, i2;
|
int i, i2;
|
||||||
SFPreset *p, *pr = NULL; /* ptr to current & previous preset */
|
SFPreset *p, *pr = NULL; /* ptr to current & previous preset */
|
||||||
|
@ -2474,7 +2512,7 @@ load_phdr (int size, SFData * sf, FILE * fd)
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{ /* at least one preset + term record */
|
{ /* at least one preset + term record */
|
||||||
FLUID_LOG (FLUID_WARN, _("File contains no presets"));
|
FLUID_LOG (FLUID_WARN, _("File contains no presets"));
|
||||||
FSKIP (SFPHDRSIZE, fd);
|
FSKIP (SFPHDRSIZE, fd, fcbs);
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2483,13 +2521,13 @@ load_phdr (int size, SFData * sf, FILE * fd)
|
||||||
p = FLUID_NEW (SFPreset);
|
p = FLUID_NEW (SFPreset);
|
||||||
sf->preset = fluid_list_append (sf->preset, p);
|
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, sfont_close can cleanup */
|
||||||
READSTR (&p->name, fd); /* possible read failure ^ */
|
READSTR (&p->name, fd, fcbs); /* possible read failure ^ */
|
||||||
READW (p->prenum, fd);
|
READW (p->prenum, fd, fcbs);
|
||||||
READW (p->bank, fd);
|
READW (p->bank, fd, fcbs);
|
||||||
READW (zndx, fd);
|
READW (zndx, fd, fcbs);
|
||||||
READD (p->libr, fd);
|
READD (p->libr, fd, fcbs);
|
||||||
READD (p->genre, fd);
|
READD (p->genre, fd, fcbs);
|
||||||
READD (p->morph, fd);
|
READD (p->morph, fd, fcbs);
|
||||||
|
|
||||||
if (pr)
|
if (pr)
|
||||||
{ /* not first preset? */
|
{ /* not first preset? */
|
||||||
|
@ -2507,9 +2545,9 @@ load_phdr (int size, SFData * sf, FILE * fd)
|
||||||
pzndx = zndx;
|
pzndx = zndx;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSKIP (24, fd);
|
FSKIP (24, fd, fcbs);
|
||||||
READW (zndx, fd); /* Read terminal generator index */
|
READW (zndx, fd, fcbs); /* Read terminal generator index */
|
||||||
FSKIP (12, fd);
|
FSKIP (12, fd, fcbs);
|
||||||
|
|
||||||
if (zndx < pzndx)
|
if (zndx < pzndx)
|
||||||
return (gerr (ErrCorr, _("Preset header indices not monotonic")));
|
return (gerr (ErrCorr, _("Preset header indices not monotonic")));
|
||||||
|
@ -2524,7 +2562,7 @@ load_phdr (int size, SFData * sf, FILE * fd)
|
||||||
|
|
||||||
/* preset bag loader */
|
/* preset bag loader */
|
||||||
static int
|
static int
|
||||||
load_pbag (int size, SFData * sf, FILE * fd)
|
load_pbag (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2;
|
fluid_list_t *p, *p2;
|
||||||
SFZone *z, *pz = NULL;
|
SFZone *z, *pz = NULL;
|
||||||
|
@ -2547,8 +2585,8 @@ load_pbag (int size, SFData * sf, FILE * fd)
|
||||||
p2->data = z;
|
p2->data = z;
|
||||||
z->gen = NULL; /* Init gen and mod before possible failure, */
|
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 (sfont_close) */
|
||||||
READW (genndx, fd); /* possible read failure ^ */
|
READW (genndx, fd, fcbs); /* possible read failure ^ */
|
||||||
READW (modndx, fd);
|
READW (modndx, fd, fcbs);
|
||||||
z->instsamp = NULL;
|
z->instsamp = NULL;
|
||||||
|
|
||||||
if (pz)
|
if (pz)
|
||||||
|
@ -2578,8 +2616,8 @@ load_pbag (int size, SFData * sf, FILE * fd)
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return (gerr (ErrCorr, _("Preset bag chunk size mismatch")));
|
return (gerr (ErrCorr, _("Preset bag chunk size mismatch")));
|
||||||
|
|
||||||
READW (genndx, fd);
|
READW (genndx, fd, fcbs);
|
||||||
READW (modndx, fd);
|
READW (modndx, fd, fcbs);
|
||||||
|
|
||||||
if (!pz)
|
if (!pz)
|
||||||
{
|
{
|
||||||
|
@ -2606,7 +2644,7 @@ load_pbag (int size, SFData * sf, FILE * fd)
|
||||||
|
|
||||||
/* preset modulator loader */
|
/* preset modulator loader */
|
||||||
static int
|
static int
|
||||||
load_pmod (int size, SFData * sf, FILE * fd)
|
load_pmod (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2, *p3;
|
fluid_list_t *p, *p2, *p3;
|
||||||
SFMod *m;
|
SFMod *m;
|
||||||
|
@ -2625,11 +2663,11 @@ load_pmod (int size, SFData * sf, FILE * fd)
|
||||||
_("Preset modulator chunk size mismatch")));
|
_("Preset modulator chunk size mismatch")));
|
||||||
m = FLUID_NEW (SFMod);
|
m = FLUID_NEW (SFMod);
|
||||||
p3->data = m;
|
p3->data = m;
|
||||||
READW (m->src, fd);
|
READW (m->src, fd, fcbs);
|
||||||
READW (m->dest, fd);
|
READW (m->dest, fd, fcbs);
|
||||||
READW (m->amount, fd);
|
READW (m->amount, fd, fcbs);
|
||||||
READW (m->amtsrc, fd);
|
READW (m->amtsrc, fd, fcbs);
|
||||||
READW (m->trans, fd);
|
READW (m->trans, fd, fcbs);
|
||||||
p3 = fluid_list_next (p3);
|
p3 = fluid_list_next (p3);
|
||||||
}
|
}
|
||||||
p2 = fluid_list_next (p2);
|
p2 = fluid_list_next (p2);
|
||||||
|
@ -2647,7 +2685,7 @@ load_pmod (int size, SFData * sf, FILE * fd)
|
||||||
size -= SFMODSIZE;
|
size -= SFMODSIZE;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return (gerr (ErrCorr, _("Preset modulator chunk size mismatch")));
|
return (gerr (ErrCorr, _("Preset modulator chunk size mismatch")));
|
||||||
FSKIP (SFMODSIZE, fd); /* terminal mod */
|
FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
@ -2665,7 +2703,7 @@ load_pmod (int size, SFData * sf, FILE * fd)
|
||||||
* if a duplicate generator exists replace previous one
|
* if a duplicate generator exists replace previous one
|
||||||
* ------------------------------------------------------------------- */
|
* ------------------------------------------------------------------- */
|
||||||
static int
|
static int
|
||||||
load_pgen (int size, SFData * sf, FILE * fd)
|
load_pgen (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
|
fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
|
||||||
SFZone *z;
|
SFZone *z;
|
||||||
|
@ -2696,15 +2734,15 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
return (gerr (ErrCorr,
|
return (gerr (ErrCorr,
|
||||||
_("Preset generator chunk size mismatch")));
|
_("Preset generator chunk size mismatch")));
|
||||||
|
|
||||||
READW (genid, fd);
|
READW (genid, fd, fcbs);
|
||||||
|
|
||||||
if (genid == Gen_KeyRange)
|
if (genid == Gen_KeyRange)
|
||||||
{ /* nothing precedes */
|
{ /* nothing precedes */
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
{
|
{
|
||||||
level = 1;
|
level = 1;
|
||||||
READB (genval.range.lo, fd);
|
READB (genval.range.lo, fd, fcbs);
|
||||||
READB (genval.range.hi, fd);
|
READB (genval.range.hi, fd, fcbs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
skip = TRUE;
|
skip = TRUE;
|
||||||
|
@ -2714,8 +2752,8 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
if (level <= 1)
|
if (level <= 1)
|
||||||
{
|
{
|
||||||
level = 2;
|
level = 2;
|
||||||
READB (genval.range.lo, fd);
|
READB (genval.range.lo, fd, fcbs);
|
||||||
READB (genval.range.hi, fd);
|
READB (genval.range.hi, fd, fcbs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
skip = TRUE;
|
skip = TRUE;
|
||||||
|
@ -2723,7 +2761,7 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
else if (genid == Gen_Instrument)
|
else if (genid == Gen_Instrument)
|
||||||
{ /* inst is last gen */
|
{ /* inst is last gen */
|
||||||
level = 3;
|
level = 3;
|
||||||
READW (genval.uword, fd);
|
READW (genval.uword, fd, fcbs);
|
||||||
((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1);
|
((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1);
|
||||||
break; /* break out of generator loop */
|
break; /* break out of generator loop */
|
||||||
}
|
}
|
||||||
|
@ -2732,7 +2770,7 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
level = 2;
|
level = 2;
|
||||||
if (gen_validp (genid))
|
if (gen_validp (genid))
|
||||||
{ /* generator valid? */
|
{ /* generator valid? */
|
||||||
READW (genval.sword, fd);
|
READW (genval.sword, fd, fcbs);
|
||||||
dup = gen_inlist (genid, z->gen);
|
dup = gen_inlist (genid, z->gen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2758,7 +2796,7 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
{ /* Skip this generator */
|
{ /* Skip this generator */
|
||||||
discarded = TRUE;
|
discarded = TRUE;
|
||||||
drop = TRUE;
|
drop = TRUE;
|
||||||
FSKIPW (fd);
|
FSKIPW (fd, fcbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drop)
|
if (!drop)
|
||||||
|
@ -2803,7 +2841,7 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
if ((size -= SFGENSIZE) < 0)
|
if ((size -= SFGENSIZE) < 0)
|
||||||
return (gerr (ErrCorr,
|
return (gerr (ErrCorr,
|
||||||
_("Preset generator chunk size mismatch")));
|
_("Preset generator chunk size mismatch")));
|
||||||
FSKIP (SFGENSIZE, fd);
|
FSKIP (SFGENSIZE, fd, fcbs);
|
||||||
SLADVREM (z->gen, p3);
|
SLADVREM (z->gen, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2823,14 +2861,14 @@ load_pgen (int size, SFData * sf, FILE * fd)
|
||||||
size -= SFGENSIZE;
|
size -= SFGENSIZE;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return (gerr (ErrCorr, _("Preset generator chunk size mismatch")));
|
return (gerr (ErrCorr, _("Preset generator chunk size mismatch")));
|
||||||
FSKIP (SFGENSIZE, fd); /* terminal gen */
|
FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* instrument header loader */
|
/* instrument header loader */
|
||||||
static int
|
static int
|
||||||
load_ihdr (int size, SFData * sf, FILE * fd)
|
load_ihdr (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
int i, i2;
|
int i, i2;
|
||||||
SFInst *p, *pr = NULL; /* ptr to current & previous instrument */
|
SFInst *p, *pr = NULL; /* ptr to current & previous instrument */
|
||||||
|
@ -2843,7 +2881,7 @@ load_ihdr (int size, SFData * sf, FILE * fd)
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{ /* at least one preset + term record */
|
{ /* at least one preset + term record */
|
||||||
FLUID_LOG (FLUID_WARN, _("File contains no instruments"));
|
FLUID_LOG (FLUID_WARN, _("File contains no instruments"));
|
||||||
FSKIP (SFIHDRSIZE, fd);
|
FSKIP (SFIHDRSIZE, fd, fcbs);
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2852,8 +2890,8 @@ load_ihdr (int size, SFData * sf, FILE * fd)
|
||||||
p = FLUID_NEW (SFInst);
|
p = FLUID_NEW (SFInst);
|
||||||
sf->inst = fluid_list_append (sf->inst, p);
|
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 (sfont_close) */
|
||||||
READSTR (&p->name, fd); /* Possible read failure ^ */
|
READSTR (&p->name, fd, fcbs); /* Possible read failure ^ */
|
||||||
READW (zndx, fd);
|
READW (zndx, fd, fcbs);
|
||||||
|
|
||||||
if (pr)
|
if (pr)
|
||||||
{ /* not first instrument? */
|
{ /* not first instrument? */
|
||||||
|
@ -2871,8 +2909,8 @@ load_ihdr (int size, SFData * sf, FILE * fd)
|
||||||
pr = p; /* update instrument ptr */
|
pr = p; /* update instrument ptr */
|
||||||
}
|
}
|
||||||
|
|
||||||
FSKIP (20, fd);
|
FSKIP (20, fd, fcbs);
|
||||||
READW (zndx, fd);
|
READW (zndx, fd, fcbs);
|
||||||
|
|
||||||
if (zndx < pzndx)
|
if (zndx < pzndx)
|
||||||
return (gerr (ErrCorr, _("Instrument header indices not monotonic")));
|
return (gerr (ErrCorr, _("Instrument header indices not monotonic")));
|
||||||
|
@ -2885,7 +2923,7 @@ load_ihdr (int size, SFData * sf, FILE * fd)
|
||||||
|
|
||||||
/* instrument bag loader */
|
/* instrument bag loader */
|
||||||
static int
|
static int
|
||||||
load_ibag (int size, SFData * sf, FILE * fd)
|
load_ibag (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2;
|
fluid_list_t *p, *p2;
|
||||||
SFZone *z, *pz = NULL;
|
SFZone *z, *pz = NULL;
|
||||||
|
@ -2907,8 +2945,8 @@ load_ibag (int size, SFData * sf, FILE * fd)
|
||||||
p2->data = z;
|
p2->data = z;
|
||||||
z->gen = NULL; /* In case of failure, */
|
z->gen = NULL; /* In case of failure, */
|
||||||
z->mod = NULL; /* sfont_close can clean up */
|
z->mod = NULL; /* sfont_close can clean up */
|
||||||
READW (genndx, fd); /* READW = possible read failure */
|
READW (genndx, fd, fcbs); /* READW = possible read failure */
|
||||||
READW (modndx, fd);
|
READW (modndx, fd, fcbs);
|
||||||
z->instsamp = NULL;
|
z->instsamp = NULL;
|
||||||
|
|
||||||
if (pz)
|
if (pz)
|
||||||
|
@ -2938,8 +2976,8 @@ load_ibag (int size, SFData * sf, FILE * fd)
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return (gerr (ErrCorr, _("Instrument chunk size mismatch")));
|
return (gerr (ErrCorr, _("Instrument chunk size mismatch")));
|
||||||
|
|
||||||
READW (genndx, fd);
|
READW (genndx, fd, fcbs);
|
||||||
READW (modndx, fd);
|
READW (modndx, fd, fcbs);
|
||||||
|
|
||||||
if (!pz)
|
if (!pz)
|
||||||
{ /* in case that all are no zoners */
|
{ /* in case that all are no zoners */
|
||||||
|
@ -2968,7 +3006,7 @@ load_ibag (int size, SFData * sf, FILE * fd)
|
||||||
|
|
||||||
/* instrument modulator loader */
|
/* instrument modulator loader */
|
||||||
static int
|
static int
|
||||||
load_imod (int size, SFData * sf, FILE * fd)
|
load_imod (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2, *p3;
|
fluid_list_t *p, *p2, *p3;
|
||||||
SFMod *m;
|
SFMod *m;
|
||||||
|
@ -2987,11 +3025,11 @@ load_imod (int size, SFData * sf, FILE * fd)
|
||||||
_("Instrument modulator chunk size mismatch")));
|
_("Instrument modulator chunk size mismatch")));
|
||||||
m = FLUID_NEW (SFMod);
|
m = FLUID_NEW (SFMod);
|
||||||
p3->data = m;
|
p3->data = m;
|
||||||
READW (m->src, fd);
|
READW (m->src, fd, fcbs);
|
||||||
READW (m->dest, fd);
|
READW (m->dest, fd, fcbs);
|
||||||
READW (m->amount, fd);
|
READW (m->amount, fd, fcbs);
|
||||||
READW (m->amtsrc, fd);
|
READW (m->amtsrc, fd, fcbs);
|
||||||
READW (m->trans, fd);
|
READW (m->trans, fd, fcbs);
|
||||||
p3 = fluid_list_next (p3);
|
p3 = fluid_list_next (p3);
|
||||||
}
|
}
|
||||||
p2 = fluid_list_next (p2);
|
p2 = fluid_list_next (p2);
|
||||||
|
@ -3009,14 +3047,14 @@ load_imod (int size, SFData * sf, FILE * fd)
|
||||||
size -= SFMODSIZE;
|
size -= SFMODSIZE;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch")));
|
return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch")));
|
||||||
FSKIP (SFMODSIZE, fd); /* terminal mod */
|
FSKIP (SFMODSIZE, fd, fcbs); /* terminal mod */
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load instrument generators (see load_pgen for loading rules) */
|
/* load instrument generators (see load_pgen for loading rules) */
|
||||||
static int
|
static int
|
||||||
load_igen (int size, SFData * sf, FILE * fd)
|
load_igen (int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
|
fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
|
||||||
SFZone *z;
|
SFZone *z;
|
||||||
|
@ -3046,15 +3084,15 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
if ((size -= SFGENSIZE) < 0)
|
if ((size -= SFGENSIZE) < 0)
|
||||||
return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
|
return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
|
||||||
|
|
||||||
READW (genid, fd);
|
READW (genid, fd, fcbs);
|
||||||
|
|
||||||
if (genid == Gen_KeyRange)
|
if (genid == Gen_KeyRange)
|
||||||
{ /* nothing precedes */
|
{ /* nothing precedes */
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
{
|
{
|
||||||
level = 1;
|
level = 1;
|
||||||
READB (genval.range.lo, fd);
|
READB (genval.range.lo, fd, fcbs);
|
||||||
READB (genval.range.hi, fd);
|
READB (genval.range.hi, fd, fcbs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
skip = TRUE;
|
skip = TRUE;
|
||||||
|
@ -3064,8 +3102,8 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
if (level <= 1)
|
if (level <= 1)
|
||||||
{
|
{
|
||||||
level = 2;
|
level = 2;
|
||||||
READB (genval.range.lo, fd);
|
READB (genval.range.lo, fd, fcbs);
|
||||||
READB (genval.range.hi, fd);
|
READB (genval.range.hi, fd, fcbs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
skip = TRUE;
|
skip = TRUE;
|
||||||
|
@ -3073,7 +3111,7 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
else if (genid == Gen_SampleId)
|
else if (genid == Gen_SampleId)
|
||||||
{ /* sample is last gen */
|
{ /* sample is last gen */
|
||||||
level = 3;
|
level = 3;
|
||||||
READW (genval.uword, fd);
|
READW (genval.uword, fd, fcbs);
|
||||||
((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1);
|
((SFZone *) (p2->data))->instsamp = FLUID_INT_TO_POINTER (genval.uword + 1);
|
||||||
break; /* break out of generator loop */
|
break; /* break out of generator loop */
|
||||||
}
|
}
|
||||||
|
@ -3082,7 +3120,7 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
level = 2;
|
level = 2;
|
||||||
if (gen_valid (genid))
|
if (gen_valid (genid))
|
||||||
{ /* gen valid? */
|
{ /* gen valid? */
|
||||||
READW (genval.sword, fd);
|
READW (genval.sword, fd, fcbs);
|
||||||
dup = gen_inlist (genid, z->gen);
|
dup = gen_inlist (genid, z->gen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3108,7 +3146,7 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
{ /* skip this generator */
|
{ /* skip this generator */
|
||||||
discarded = TRUE;
|
discarded = TRUE;
|
||||||
drop = TRUE;
|
drop = TRUE;
|
||||||
FSKIPW (fd);
|
FSKIPW (fd, fcbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drop)
|
if (!drop)
|
||||||
|
@ -3153,7 +3191,7 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
if ((size -= SFGENSIZE) < 0)
|
if ((size -= SFGENSIZE) < 0)
|
||||||
return (gerr (ErrCorr,
|
return (gerr (ErrCorr,
|
||||||
_("Instrument generator chunk size mismatch")));
|
_("Instrument generator chunk size mismatch")));
|
||||||
FSKIP (SFGENSIZE, fd);
|
FSKIP (SFGENSIZE, fd, fcbs);
|
||||||
SLADVREM (z->gen, p3);
|
SLADVREM (z->gen, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3173,14 +3211,14 @@ load_igen (int size, SFData * sf, FILE * fd)
|
||||||
size -= SFGENSIZE;
|
size -= SFGENSIZE;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
|
return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
|
||||||
FSKIP (SFGENSIZE, fd); /* terminal gen */
|
FSKIP (SFGENSIZE, fd, fcbs); /* terminal gen */
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sample header loader */
|
/* sample header loader */
|
||||||
static int
|
static int
|
||||||
load_shdr (unsigned int size, SFData * sf, FILE * fd)
|
load_shdr (unsigned int size, SFData * sf, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
SFSample *p;
|
SFSample *p;
|
||||||
|
@ -3192,7 +3230,7 @@ load_shdr (unsigned int size, SFData * sf, FILE * fd)
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{ /* at least one sample + term record? */
|
{ /* at least one sample + term record? */
|
||||||
FLUID_LOG (FLUID_WARN, _("File contains no samples"));
|
FLUID_LOG (FLUID_WARN, _("File contains no samples"));
|
||||||
FSKIP (SFSHDRSIZE, fd);
|
FSKIP (SFSHDRSIZE, fd, fcbs);
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3201,20 +3239,20 @@ load_shdr (unsigned int size, SFData * sf, FILE * fd)
|
||||||
{
|
{
|
||||||
p = FLUID_NEW (SFSample);
|
p = FLUID_NEW (SFSample);
|
||||||
sf->sample = fluid_list_append (sf->sample, p);
|
sf->sample = fluid_list_append (sf->sample, p);
|
||||||
READSTR (&p->name, fd);
|
READSTR (&p->name, fd, fcbs);
|
||||||
READD (p->start, fd);
|
READD (p->start, fd, fcbs);
|
||||||
READD (p->end, fd); /* - end, loopstart and loopend */
|
READD (p->end, fd, fcbs); /* - end, loopstart and loopend */
|
||||||
READD (p->loopstart, fd); /* - will be checked and turned into */
|
READD (p->loopstart, fd, fcbs); /* - will be checked and turned into */
|
||||||
READD (p->loopend, fd); /* - offsets in fixup_sample() */
|
READD (p->loopend, fd, fcbs); /* - offsets in fixup_sample() */
|
||||||
READD (p->samplerate, fd);
|
READD (p->samplerate, fd, fcbs);
|
||||||
READB (p->origpitch, fd);
|
READB (p->origpitch, fd, fcbs);
|
||||||
READB (p->pitchadj, fd);
|
READB (p->pitchadj, fd, fcbs);
|
||||||
FSKIPW (fd); /* skip sample link */
|
FSKIPW (fd, fcbs); /* skip sample link */
|
||||||
READW (p->sampletype, fd);
|
READW (p->sampletype, fd, fcbs);
|
||||||
p->samfile = 0;
|
p->samfile = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSKIP (SFSHDRSIZE, fd); /* skip terminal shdr */
|
FSKIP (SFSHDRSIZE, fd, fcbs); /* skip terminal shdr */
|
||||||
|
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
@ -3408,12 +3446,12 @@ static const unsigned short badpgen[] = {
|
||||||
|
|
||||||
/* close SoundFont file and delete a SoundFont structure */
|
/* close SoundFont file and delete a SoundFont structure */
|
||||||
void
|
void
|
||||||
sfont_close (SFData * sf)
|
sfont_close (SFData * sf, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
fluid_list_t *p, *p2;
|
fluid_list_t *p, *p2;
|
||||||
|
|
||||||
if (sf->sffd)
|
if (sf->sffd)
|
||||||
fclose (sf->sffd);
|
fcbs->fclose (sf->sffd);
|
||||||
|
|
||||||
if (sf->fname)
|
if (sf->fname)
|
||||||
free (sf->fname);
|
free (sf->fname);
|
||||||
|
@ -3583,9 +3621,9 @@ gerr (int ev, char * fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
safe_fread (void *buf, int count, FILE * fd)
|
safe_fread (void *buf, int count, void * fd, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
if (fread (buf, count, 1, fd) != 1)
|
if (fcbs->fread (buf, count, 1, fd) != 1)
|
||||||
{ /* size_t = count, nmemb = 1 */
|
{ /* size_t = count, nmemb = 1 */
|
||||||
if (feof (fd))
|
if (feof (fd))
|
||||||
gerr (ErrEof, _("EOF while attemping to read %d bytes"), count);
|
gerr (ErrEof, _("EOF while attemping to read %d bytes"), count);
|
||||||
|
@ -3597,9 +3635,9 @@ safe_fread (void *buf, int count, FILE * fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
safe_fseek (FILE * fd, long ofs, int whence)
|
safe_fseek (void * fd, long ofs, int whence, fluid_file_callbacks_t* fcbs)
|
||||||
{
|
{
|
||||||
if (fseek (fd, ofs, whence) == -1) {
|
if (fcbs->fseek (fd, ofs, whence) == -1) {
|
||||||
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 (FAIL);
|
return (FAIL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ Gen_Unit;
|
||||||
/* functions */
|
/* functions */
|
||||||
void sfont_init_chunks (void);
|
void sfont_init_chunks (void);
|
||||||
|
|
||||||
void sfont_close (SFData * sf);
|
void sfont_close (SFData * sf, fluid_file_callbacks_t* cbs);
|
||||||
void sfont_free_zone (SFZone * zone);
|
void sfont_free_zone (SFZone * zone);
|
||||||
int sfont_preset_compare_func (void* a, void* b);
|
int sfont_preset_compare_func (void* a, void* b);
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ typedef struct _SFShdr
|
||||||
SFShdr;
|
SFShdr;
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
SFData *sfload_file (const char * fname);
|
SFData *sfload_file (const char * fname, fluid_file_callbacks_t* cbs);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,9 +319,9 @@ enum
|
||||||
#define ErrnoEnd ErrWrite
|
#define ErrnoEnd ErrWrite
|
||||||
|
|
||||||
int gerr (int ev, char * fmt, ...);
|
int gerr (int ev, char * fmt, ...);
|
||||||
int safe_fread (void *buf, int count, FILE * fd);
|
int safe_fread (void *buf, int count, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
int safe_fwrite (void *buf, int count, FILE * fd);
|
int safe_fwrite (void *buf, int count, void * fd, fluid_file_callbacks_t* fcbs);
|
||||||
int safe_fseek (FILE * fd, long ofs, int whence);
|
int safe_fseek (void * fd, long ofs, int whence, fluid_file_callbacks_t* fcbs);
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
|
@ -391,12 +391,12 @@ struct _fluid_defsfont_t
|
||||||
|
|
||||||
fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings);
|
fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings);
|
||||||
int delete_fluid_defsfont(fluid_defsfont_t* sfont);
|
int delete_fluid_defsfont(fluid_defsfont_t* sfont);
|
||||||
int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file);
|
int fluid_defsfont_load(fluid_defsfont_t* sfont, fluid_file_callbacks_t* file_callbacks, const char* file);
|
||||||
const char* fluid_defsfont_get_name(fluid_defsfont_t* sfont);
|
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);
|
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);
|
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_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset);
|
||||||
int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont);
|
int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont, fluid_file_callbacks_t* file_callbacks);
|
||||||
int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample);
|
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 fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue