mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 06:51:54 +00:00
Merge pull request #291 from FluidSynth/file-callback
Add file callbacks to fluid_sfloader_t
This commit is contained in:
commit
c94f747c04
9 changed files with 399 additions and 226 deletions
|
@ -85,13 +85,13 @@ Changes in FluidSynth 2.0.0 concerning developers:
|
|||
- remove fluid_synth_set_gen2(), fluid_synth_set_gen() now behaves as fluid_synth_set_gen2()
|
||||
- remove struct fluid_mod_t from public API, use the getters and setters of mod.h instead
|
||||
- remove struct _fluid_gen_t, fluid_gen_set_default_values() and enum fluid_gen_flags from public API
|
||||
|
||||
<br /><br />
|
||||
- all public \c fluid_settings_* functions that return an integer which is not meant to be interpreted as bool consistently return either FLUID_OK or FLUID_FAILED
|
||||
- all public delete_* functions return void and are safe when called with NULL
|
||||
- the shell command handler was decoupled internally, as a consequence the param list of new_fluid_server() and new_fluid_cmd_handler() was adapted
|
||||
- reverb: roomsize is now limited to an upper threshold of 1.0
|
||||
- use unique device names for the "audio.portaudio.device" setting
|
||||
|
||||
<br /><br />
|
||||
- add "synth.volenv" a setting for volume envelope processing
|
||||
- add "midi.autoconnect" a setting for automatically connecting fluidsynth to available MIDI input ports
|
||||
- add support for polyonic key pressure events, see fluid_event_key_pressure()
|
||||
|
@ -99,6 +99,7 @@ Changes in FluidSynth 2.0.0 concerning developers:
|
|||
- add individual reverb setters: fluid_synth_set_reverb_roomsize(), fluid_synth_set_reverb_damp(), fluid_synth_set_reverb_width(), fluid_synth_set_reverb_level()
|
||||
- add individual chorus setters: fluid_synth_set_chorus_nr(), fluid_synth_set_chorus_level(), fluid_synth_set_chorus_speed(), fluid_synth_set_chorus_depth(), fluid_synth_set_chorus_type()
|
||||
- introduce a separate data type for sequencer client IDs: #fluid_seq_id_t
|
||||
- add file callback struct to _fluid_sfloader_t and expose new_fluid_defsfloader() to enable soundfont loading from memory ( see fluid_sfload_mem.c )
|
||||
|
||||
|
||||
\section NewIn1_1_9 Whats new in 1.1.9?
|
||||
|
@ -797,3 +798,8 @@ Example of an arpeggio generated using the MIDI sequencer API
|
|||
\example fluidsynth_register_adriver.c
|
||||
Example of how to register audio drivers using fluid_audio_driver_register() (advanced users only)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\example fluidsynth_sfload_mem.c
|
||||
Example of how read a soundfont from memory (advanced users only)
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*
|
||||
* This is a simple C99 program that demonstrates the usage of fluid_audio_driver_register()
|
||||
*
|
||||
* There are 3 calls to fluid_audio_driver_register(), i.e. 3 iterations:
|
||||
|
|
95
doc/fluidsynth_sfload_mem.c
Normal file
95
doc/fluidsynth_sfload_mem.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* This is a C99 program that demonstrates how to load a soundfont from memory.
|
||||
*
|
||||
* It only gives a brief overview on how to achieve this with fluidsynth's API.
|
||||
* Although it should compile, it's highly incomplete, as the details of it's
|
||||
* implementation depend on the users needs.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fluidsynth.h>
|
||||
|
||||
void * my_open(const char * filename)
|
||||
{
|
||||
void* p;
|
||||
if(filename[0] != '&')
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
scanf("&%p", &p);
|
||||
return p;
|
||||
}
|
||||
|
||||
int my_read(void *buf, int count, void * handle)
|
||||
{
|
||||
// not yet implemented
|
||||
memset(buf, 0, count);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int my_seek(void * handle, long offset, int origin)
|
||||
{
|
||||
// NYI
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int my_close(void * handle)
|
||||
{
|
||||
// NYI
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
long my_tell(void * handle)
|
||||
{
|
||||
// NYI
|
||||
return 0;
|
||||
}
|
||||
|
||||
fluid_file_callbacks_t my_cb =
|
||||
{
|
||||
.fopen = my_open,
|
||||
.fread = my_read,
|
||||
.fseek = my_seek,
|
||||
.fclose = my_close,
|
||||
.ftell = my_tell
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
fluid_settings_t* settings = new_fluid_settings();
|
||||
fluid_synth_t* synth = new_fluid_synth(settings);
|
||||
|
||||
fluid_sfloader_t* my_sfloader = new_fluid_defsfloader(settings);
|
||||
my_sfloader->file_callbacks = &my_cb;
|
||||
fluid_synth_add_sfloader(synth, my_sfloader);
|
||||
|
||||
|
||||
char abused_filename[64];
|
||||
const void* pointer_to_sf2_in_mem = 0x1234Beef; // some pointer to where the soundfont shall be loaded from
|
||||
sprintf(abused_filename, "&%p", pointer_to_sf2_in_mem);
|
||||
|
||||
int id = fluid_synth_sfload(synth, abused_filename, 0);
|
||||
/* now my_open() will be called with abused_filename and should have opened the memory region */
|
||||
|
||||
if(id == FLUID_FAILED)
|
||||
{
|
||||
puts("oops");
|
||||
err = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* ~~~ Do your daily business here ~~~
|
||||
*/
|
||||
|
||||
cleanup:
|
||||
/* deleting the synth also deletes my_sfloader */
|
||||
delete_fluid_synth(synth);
|
||||
|
||||
delete_fluid_settings(settings);
|
||||
|
||||
return err;
|
||||
}
|
|
@ -75,15 +75,17 @@ enum {
|
|||
* SoundFont loader structure.
|
||||
*/
|
||||
struct _fluid_sfloader_t {
|
||||
void* data; /**< User defined data pointer */
|
||||
void* data; /**< User defined data pointer used by _fluid_sfloader_t::load() */
|
||||
|
||||
/**
|
||||
* The free method should free the memory allocated for the loader in
|
||||
/** Callback structure specifying file operations used during soundfont loading to allow custom loading, such as from memory */
|
||||
const fluid_file_callbacks_t* file_callbacks;
|
||||
|
||||
/**
|
||||
* The free method should free the memory allocated for this loader instance in
|
||||
* addition to any private data.
|
||||
* @param loader SoundFont loader
|
||||
* @return Should return 0 if no error occured, non-zero otherwise
|
||||
*/
|
||||
int (*free)(fluid_sfloader_t* loader);
|
||||
void (*free)(fluid_sfloader_t* loader);
|
||||
|
||||
/**
|
||||
* Method to load an instrument file (does not actually need to be a real file name,
|
||||
|
@ -96,6 +98,46 @@ struct _fluid_sfloader_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* File callback structure to enable custom soundfont loading (e.g. from memory).
|
||||
*/
|
||||
struct _fluid_file_callbacks_t {
|
||||
/**
|
||||
* Opens the file or memory indicated by \c filename in binary read mode.
|
||||
* \c filename matches the one provided during the fluid_synth_sfload() call.
|
||||
*
|
||||
* @return returns a file handle on success, NULL otherwise
|
||||
*/
|
||||
void * (* fopen )(const char * filename);
|
||||
|
||||
/**
|
||||
* Reads \c count bytes to the specified buffer \c buf.
|
||||
*
|
||||
* @return returns #FLUID_OK if exactly \c count bytes were successfully read, else #FLUID_FAILED
|
||||
*/
|
||||
int (* fread )(void *buf, int count, void * handle);
|
||||
|
||||
/**
|
||||
* Same purpose and behaviour as fseek.
|
||||
*
|
||||
* @param origin either \c SEEK_SET, \c SEEK_CUR or \c SEEK_END
|
||||
*
|
||||
* @return returns #FLUID_OK if the seek was successfully performed while not seeking beyond a buffer or file, #FLUID_FAILED otherwise */
|
||||
int (* fseek )(void * handle, long offset, int origin);
|
||||
|
||||
/**
|
||||
* Closes the handle and frees used ressources.
|
||||
*
|
||||
* @return returns #FLUID_OK on success, #FLUID_FAILED on error */
|
||||
int (* fclose)(void * handle);
|
||||
|
||||
/** @return returns current file offset or #FLUID_FAILED on error */
|
||||
long (* ftell )(void * handle);
|
||||
};
|
||||
|
||||
|
||||
FLUIDSYNTH_API fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings);
|
||||
|
||||
/*
|
||||
* Virtual SoundFont instance structure.
|
||||
*/
|
||||
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_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_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_ostream_t; /**< Output stream descriptor */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -215,7 +215,7 @@ Gen_Unit;
|
|||
/* functions */
|
||||
void sfont_init_chunks (void);
|
||||
|
||||
void sfont_close (SFData * sf);
|
||||
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);
|
||||
|
||||
|
@ -291,7 +291,7 @@ typedef struct _SFShdr
|
|||
SFShdr;
|
||||
|
||||
/* functions */
|
||||
SFData *sfload_file (const char * fname);
|
||||
SFData *sfload_file (const char * fname, const fluid_file_callbacks_t* fcbs);
|
||||
|
||||
|
||||
|
||||
|
@ -319,9 +319,6 @@ enum
|
|||
#define ErrnoEnd ErrWrite
|
||||
|
||||
int gerr (int ev, char * fmt, ...);
|
||||
int safe_fread (void *buf, int count, FILE * fd);
|
||||
int safe_fwrite (void *buf, int count, FILE * fd);
|
||||
int safe_fseek (FILE * fd, long ofs, int whence);
|
||||
|
||||
|
||||
/********************************************************************************/
|
||||
|
@ -348,8 +345,7 @@ typedef struct _fluid_inst_zone_t fluid_inst_zone_t;
|
|||
|
||||
*/
|
||||
|
||||
fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings);
|
||||
int delete_fluid_defsfloader(fluid_sfloader_t* loader);
|
||||
void delete_fluid_defsfloader(fluid_sfloader_t* loader);
|
||||
fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename);
|
||||
|
||||
|
||||
|
@ -391,12 +387,12 @@ 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 char* file);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
|
|
@ -3365,10 +3365,10 @@ fluid_synth_start_voice(fluid_synth_t* synth, fluid_voice_t* voice)
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a SoundFont loader interface.
|
||||
* Add a SoundFont loader to the synth. This function takes ownership of \c loader
|
||||
* and frees it automatically upon \c synth destruction.
|
||||
* @param synth FluidSynth instance
|
||||
* @param loader Loader API structure, used directly and should remain allocated
|
||||
* as long as the synth instance is used.
|
||||
* @param loader Loader API structure
|
||||
*
|
||||
* SoundFont loaders are used to add custom instrument loading to FluidSynth.
|
||||
* The caller supplied functions for loading files, allocating presets,
|
||||
|
@ -3397,7 +3397,7 @@ fluid_synth_add_sfloader(fluid_synth_t* synth, fluid_sfloader_t* loader)
|
|||
* stack. Presets are searched starting from the SoundFont on the
|
||||
* top of the stack, working the way down the stack until a preset is found.
|
||||
*
|
||||
* @param synth SoundFont instance
|
||||
* @param synth FluidSynth instance
|
||||
* @param filename File to load
|
||||
* @param reset_presets TRUE to re-assign presets for all MIDI channels
|
||||
* @return SoundFont ID on success, FLUID_FAILED on error
|
||||
|
@ -3470,7 +3470,7 @@ new_fluid_sfont_info (fluid_synth_t *synth, fluid_sfont_t *sfont)
|
|||
|
||||
/**
|
||||
* Unload a SoundFont.
|
||||
* @param synth SoundFont instance
|
||||
* @param synth FluidSynth instance
|
||||
* @param id ID of SoundFont to unload
|
||||
* @param reset_presets TRUE to re-assign presets for all MIDI channels
|
||||
* @return FLUID_OK on success, FLUID_FAILED on error
|
||||
|
@ -3559,7 +3559,7 @@ fluid_synth_sfunload_callback(void* data, unsigned int msec)
|
|||
|
||||
/**
|
||||
* Reload a SoundFont. The SoundFont retains its ID and index on the SoundFont stack.
|
||||
* @param synth SoundFont instance
|
||||
* @param synth FluidSynth instance
|
||||
* @param id ID of SoundFont to reload
|
||||
* @return SoundFont ID on success, FLUID_FAILED on error
|
||||
*/
|
||||
|
|
|
@ -231,6 +231,7 @@ typedef FILE* fluid_file;
|
|||
#define FLUID_FCLOSE(_f) fclose(_f)
|
||||
#define FLUID_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f)
|
||||
#define FLUID_FSEEK(_f,_n,_set) fseek(_f,_n,_set)
|
||||
#define FLUID_FTELL(_f) ftell(_f)
|
||||
#define FLUID_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n)
|
||||
#define FLUID_MEMSET(_s,_c,_n) memset(_s,_c,_n)
|
||||
#define FLUID_STRLEN(_s) strlen(_s)
|
||||
|
|
Loading…
Reference in a new issue