Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

soundfont loader accessor function #394

Merged
merged 4 commits into from Jun 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 42 additions & 11 deletions include/fluidsynth/sfont.h
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/sfloader/fluid_defsfont.c
Expand Up @@ -87,15 +87,15 @@ 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)
{
delete_fluid_defsfont(defsfont);
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;
Expand Down
9 changes: 4 additions & 5 deletions src/sfloader/fluid_ramsfont.c
Expand Up @@ -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;
}
Expand Down
102 changes: 96 additions & 6 deletions src/sfloader/fluid_sfont.c
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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().
*
Expand Down
33 changes: 0 additions & 33 deletions src/sfloader/fluid_sfont.h
Expand Up @@ -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)

Expand Down Expand Up @@ -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.
*/
Expand Down