Merge pull request #394 from FluidSynth/sfaccessors

soundfont loader accessor function
This commit is contained in:
Tom M 2018-06-03 09:07:26 +02:00 committed by GitHub
commit b0e22993cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 144 additions and 57 deletions

View file

@ -31,30 +31,30 @@ extern "C" {
* @brief SoundFont plugins
*
* It is possible to add new SoundFont loaders to the
* synthesizer. The API uses a couple of "interfaces" (structures
* with callback functions): #fluid_sfloader_t, #fluid_sfont_t, and
* #fluid_preset_t. This API allows for virtual SoundFont files to be loaded
* synthesizer. This API allows for virtual SoundFont files to be loaded
* and synthesized, which may not actually be SoundFont files, as long as they
* can be represented by the SoundFont synthesis model.
*
* To add a new SoundFont loader to the synthesizer, call
* fluid_synth_add_sfloader() and pass a pointer to an
* fluid_sfloader_t structure. The important callback function in
* this structure is "load", which should try to load a file and
* returns a #fluid_sfont_t structure, or NULL if it fails.
* #fluid_sfloader_t instance created by new_fluid_sfloader().
* On creation, you must specify a callback function \p load
* that will be called for every file attempting to load it and
* if successful returns a #fluid_sfont_t instance, or NULL if it fails.
*
* The #fluid_sfont_t structure contains a callback to obtain the
* name of the SoundFont. It contains two functions to iterate
* though the contained presets, and one function to obtain a
* preset corresponding to a bank and preset number. This
* function should return a #fluid_preset_t structure.
* function should return a #fluid_preset_t instance.
*
* The #fluid_preset_t structure contains some functions to obtain
* The #fluid_preset_t instance contains some functions to obtain
* information from the preset (name, bank, number). The most
* important callback is the noteon function. The noteon function
* is called by fluidsynth internally and
* should call fluid_synth_alloc_voice() for every sample that has
* to be played. fluid_synth_alloc_voice() expects a pointer to a
* #fluid_sample_t structure and returns a pointer to the opaque
* #fluid_sample_t instance and returns a pointer to the opaque
* #fluid_voice_t structure. To set or increment the values of a
* generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
* finished initializing the voice call fluid_voice_start() to
@ -172,6 +172,26 @@ typedef const char* (*fluid_sfont_get_name_t)(fluid_sfont_t* sfont);
*/
typedef fluid_preset_t* (*fluid_sfont_get_preset_t)(fluid_sfont_t* sfont, int bank, int prenum);
/**
* Start virtual SoundFont preset iteration method.
* @param sfont Virtual SoundFont
*
* Starts/re-starts virtual preset iteration in a SoundFont.
*/
typedef void (*fluid_sfont_iteration_start_t)(fluid_sfont_t* sfont);
/**
* Virtual SoundFont preset iteration function.
* @param sfont Virtual SoundFont
* @param preset Caller supplied uninitialized buffer to fill in with current preset information
* @return NULL when no more presets are available, otherwise the a pointer to the current preset
*
* Should store preset information to the caller supplied \a preset structure
* and advance the internal iteration state to the next preset for subsequent
* calls.
*/
typedef fluid_preset_t* (*fluid_sfont_iteration_next_t)(fluid_sfont_t* sfont);
/**
* Method to free a virtual SoundFont bank. Any custom user provided cleanup function must ultimately call
* delete_fluid_sfont() to ensure proper cleanup of the #fluid_sfont_t struct. If no private data
@ -185,13 +205,21 @@ typedef int (*fluid_sfont_free_t)(fluid_sfont_t* sfont);
FLUIDSYNTH_API fluid_sfont_t* new_fluid_sfont(fluid_sfont_get_name_t get_name,
fluid_sfont_get_preset_t get_preset,
fluid_sfont_free_t free);
fluid_sfont_get_preset_t get_preset,
fluid_sfont_iteration_start_t iter_start,
fluid_sfont_iteration_next_t iter_next,
fluid_sfont_free_t free);
FLUIDSYNTH_API int delete_fluid_sfont(fluid_sfont_t* sfont);
FLUIDSYNTH_API int fluid_sfont_set_data(fluid_sfont_t* sfont, void* data);
FLUIDSYNTH_API void* fluid_sfont_get_data(fluid_sfont_t* sfont);
FLUIDSYNTH_API int fluid_sfont_get_id(fluid_sfont_t* sfont);
FLUIDSYNTH_API const char* fluid_sfont_get_name(fluid_sfont_t* sfont);
FLUIDSYNTH_API fluid_preset_t* fluid_sfont_get_preset(fluid_sfont_t* sfont, int bank, int prenum);
FLUIDSYNTH_API void fluid_sfont_iteration_start(fluid_sfont_t* sfont);
FLUIDSYNTH_API fluid_preset_t* fluid_sfont_iteration_next(fluid_sfont_t* sfont);
/**
* Method to get a virtual SoundFont preset name.
@ -260,6 +288,9 @@ FLUIDSYNTH_API void delete_fluid_preset(fluid_preset_t* preset);
FLUIDSYNTH_API int fluid_preset_set_data(fluid_preset_t* preset, void* data);
FLUIDSYNTH_API void* fluid_preset_get_data(fluid_preset_t* preset);
FLUIDSYNTH_API const char* fluid_preset_get_name(fluid_preset_t* preset);
FLUIDSYNTH_API int fluid_preset_get_banknum(fluid_preset_t* preset);
FLUIDSYNTH_API int fluid_preset_get_num(fluid_preset_t* preset);
FLUIDSYNTH_API fluid_sample_t* new_fluid_sample(void);

View file

@ -87,6 +87,8 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
sfont = new_fluid_sfont(fluid_defsfont_sfont_get_name,
fluid_defsfont_sfont_get_preset,
fluid_defsfont_sfont_iteration_start,
fluid_defsfont_sfont_iteration_next,
fluid_defsfont_sfont_delete);
if (sfont == NULL)
{
@ -94,8 +96,6 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file
return NULL;
}
fluid_sfont_set_iteration_start(sfont, fluid_defsfont_sfont_iteration_start);
fluid_sfont_set_iteration_next(sfont, fluid_defsfont_sfont_iteration_next);
fluid_sfont_set_data(sfont, defsfont);
defsfont->sfont = sfont;

View file

@ -92,18 +92,17 @@ fluid_ramsfont_create_sfont()
sfont = new_fluid_sfont(fluid_ramsfont_sfont_get_name,
fluid_ramsfont_sfont_get_preset,
fluid_ramsfont_sfont_iteration_start,
fluid_ramsfont_sfont_iteration_next,
fluid_ramsfont_sfont_delete);
if (sfont == NULL)
{
delete_fluid_ramsfont(ramsfont);
return NULL;
}
ramsfont->sfont = sfont;
fluid_sfont_set_iteration_start(sfont, fluid_ramsfont_sfont_iteration_start);
fluid_sfont_set_iteration_next(sfont, fluid_ramsfont_sfont_iteration_next);
fluid_sfont_set_data(sfont, ramsfont);
ramsfont->sfont = sfont;
return sfont;
}

View file

@ -180,11 +180,15 @@ int fluid_sfloader_set_callbacks(fluid_sfloader_t* loader,
* Creates a new virtual SoundFont instance structure.
* @param get_name A function implementing #fluid_sfont_get_name_t.
* @param get_preset A function implementing #fluid_sfont_get_preset_t.
* @param iter_start A function implementing #fluid_sfont_iteration_start_t, or NULL if preset iteration not needed.
* @param iter_next A function implementing #fluid_sfont_iteration_next_t, or NULL if preset iteration not needed.
* @param free A function implementing #fluid_sfont_free_t.
* @return The soundfont instance on success or NULL otherwise.
*/
fluid_sfont_t* new_fluid_sfont(fluid_sfont_get_name_t get_name,
fluid_sfont_get_preset_t get_preset,
fluid_sfont_iteration_start_t iter_start,
fluid_sfont_iteration_next_t iter_next,
fluid_sfont_free_t free)
{
fluid_sfont_t* sfont;
@ -203,6 +207,8 @@ fluid_sfont_t* new_fluid_sfont(fluid_sfont_get_name_t get_name,
sfont->get_name = get_name;
sfont->get_preset = get_preset;
sfont->iteration_start = iter_start;
sfont->iteration_next = iter_next;
sfont->free = free;
return sfont;
@ -237,19 +243,67 @@ void* fluid_sfont_get_data(fluid_sfont_t* sfont)
}
/**
* @internal KISS! No need to expose this to public API currently.
* Retrieve the unique ID of a SoundFont instance.
*
* @param sfont The SoundFont instance.
* @return The SoundFont ID.
*/
void fluid_sfont_set_iteration_start(fluid_sfont_t* sfont, fluid_sfont_iteration_start_t iter_start)
int fluid_sfont_get_id(fluid_sfont_t* sfont)
{
sfont->iteration_start = iter_start;
return sfont->id;
}
/**
* @internal KISS! No need to expose this to public API currently.
* Retrieve the name of a SoundFont instance.
*
* @param sfont The SoundFont instance.
* @return The name of the SoundFont.
*/
void fluid_sfont_set_iteration_next(fluid_sfont_t* sfont, fluid_sfont_iteration_next_t iter_next)
const char* fluid_sfont_get_name(fluid_sfont_t* sfont)
{
sfont->iteration_next = iter_next;
return sfont->get_name(sfont);
}
/**
* Retrieve the preset assigned the a SoundFont instance
* for the given bank and preset number.
* @param sfont The SoundFont instance.
* @param bank bank number of the preset
* @param prenum program number of the preset
* @return The preset instance or NULL if none found.
*/
fluid_preset_t* fluid_sfont_get_preset(fluid_sfont_t* sfont, int bank, int prenum)
{
return sfont->get_preset(sfont, bank, prenum);
}
/**
* Starts / re-starts virtual preset iteration in a SoundFont.
* @param sfont Virtual SoundFont instance
*/
void fluid_sfont_iteration_start(fluid_sfont_t* sfont)
{
fluid_return_if_fail(sfont != NULL);
fluid_return_if_fail(sfont->iteration_start != NULL);
sfont->iteration_start(sfont);
}
/**
* Virtual SoundFont preset iteration function.
*
* Returns preset information to the caller and advances the
* internal iteration state to the next preset for subsequent calls.
* @param sfont The SoundFont instance.
* @return NULL when no more presets are available, otherwise the a pointer to the current preset
*/
fluid_preset_t* fluid_sfont_iteration_next(fluid_sfont_t* sfont)
{
fluid_return_val_if_fail(sfont != NULL, NULL);
fluid_return_val_if_fail(sfont->iteration_next != NULL, NULL);
return sfont->iteration_next(sfont);
}
/**
@ -341,6 +395,42 @@ void* fluid_preset_get_data(fluid_preset_t* preset)
return preset->data;
}
/**
* Retrieves the presets name by executing the \p get_name function
* provided on its creation.
*
* @param preset The SoundFont preset instance.
* @return Pointer to a NULL-terminated string containing the presets name.
*/
const char* fluid_preset_get_name(fluid_preset_t* preset)
{
return preset->get_name(preset);
}
/**
* Retrieves the presets bank number by executing the \p get_bank function
* provided on its creation.
*
* @param preset The SoundFont preset instance.
* @return The bank number of \p preset.
*/
int fluid_preset_get_banknum(fluid_preset_t* preset)
{
return preset->get_banknum(preset);
}
/**
* Retrieves the presets (instrument) number by executing the \p get_num function
* provided on its creation.
*
* @param preset The SoundFont preset instance.
* @return The number of \p preset.
*/
int fluid_preset_get_num(fluid_preset_t* preset)
{
return preset->get_num(preset);
}
/**
* Destroys a SoundFont preset instance created with new_fluid_preset().
*

View file

@ -37,20 +37,10 @@ int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int max_end);
#define fluid_sfont_delete_internal(_sf) ( ((_sf) && (_sf)->free)? (*(_sf)->free)(_sf) : 0)
#define fluid_sfont_get_id(_sf) ((_sf)->id)
#define fluid_sfont_get_name(_sf) (*(_sf)->get_name)(_sf)
#define fluid_sfont_get_preset(_sf,_bank,_prenum) (*(_sf)->get_preset)(_sf,_bank,_prenum)
#define fluid_sfont_iteration_start(_sf) { if((_sf) && (_sf)->iteration_start) (*(_sf)->iteration_start)(_sf); }
#define fluid_sfont_iteration_next(_sf) (((_sf) && (_sf)->iteration_start) ? (*(_sf)->iteration_next)(_sf) : 0)
#define fluid_preset_delete_internal(_preset) \
{ if ((_preset) && (_preset)->free) { (*(_preset)->free)(_preset); }}
#define fluid_preset_get_name(_preset) (*(_preset)->get_name)(_preset)
#define fluid_preset_get_banknum(_preset) (*(_preset)->get_banknum)(_preset)
#define fluid_preset_get_num(_preset) (*(_preset)->get_num)(_preset)
#define fluid_preset_noteon(_preset,_synth,_ch,_key,_vel) \
(*(_preset)->noteon)(_preset,_synth,_ch,_key,_vel)
@ -93,29 +83,6 @@ struct _fluid_sfloader_t {
fluid_sfloader_load_t load;
};
/**
* Start virtual SoundFont preset iteration method.
* @param sfont Virtual SoundFont
*
* Starts/re-starts virtual preset iteration in a SoundFont.
*/
typedef void (*fluid_sfont_iteration_start_t)(fluid_sfont_t* sfont);
/**
* Virtual SoundFont preset iteration function.
* @param sfont Virtual SoundFont
* @param preset Caller supplied uninitialized buffer to fill in with current preset information
* @return 0 when no more presets are available, 1 otherwise
*
* Should store preset information to the caller supplied \a preset structure
* and advance the internal iteration state to the next preset for subsequent
* calls.
*/
typedef fluid_preset_t* (*fluid_sfont_iteration_next_t)(fluid_sfont_t* sfont);
void fluid_sfont_set_iteration_start(fluid_sfont_t* sfont, fluid_sfont_iteration_start_t iter_start);
void fluid_sfont_set_iteration_next(fluid_sfont_t* sfont, fluid_sfont_iteration_next_t iter_next);
/**
* Virtual SoundFont instance structure.
*/