diff options
Diffstat (limited to 'libs/fluidsynth/fluidsynth/sfont.h')
-rw-r--r-- | libs/fluidsynth/fluidsynth/sfont.h | 439 |
1 files changed, 237 insertions, 202 deletions
diff --git a/libs/fluidsynth/fluidsynth/sfont.h b/libs/fluidsynth/fluidsynth/sfont.h index 30aebfd126..55413a9e24 100644 --- a/libs/fluidsynth/fluidsynth/sfont.h +++ b/libs/fluidsynth/fluidsynth/sfont.h @@ -3,16 +3,16 @@ * Copyright (C) 2003 Peter Hanappe and others. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA @@ -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 @@ -64,215 +64,250 @@ extern "C" { /** * Some notification enums for presets and samples. */ -enum { - FLUID_PRESET_SELECTED, /**< Preset selected notify */ - FLUID_PRESET_UNSELECTED, /**< Preset unselected notify */ - FLUID_SAMPLE_DONE /**< Sample no longer needed notify */ +enum +{ + FLUID_PRESET_SELECTED, /**< Preset selected notify */ + FLUID_PRESET_UNSELECTED, /**< Preset unselected notify */ + FLUID_SAMPLE_DONE /**< Sample no longer needed notify */ }; - /** - * SoundFont loader structure. + * Indicates the type of a sample used by the _fluid_sample_t::sampletype field. */ -struct _fluid_sfloader_t { - void* data; /**< User defined data pointer */ - - /** - * The free method should free the memory allocated for the loader 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); - - /** - * Method to load an instrument file (does not actually need to be a real file name, - * could be another type of string identifier that the \a loader understands). - * @param loader SoundFont loader - * @param filename File name or other string identifier - * @return The loaded instrument file (SoundFont) or NULL if an error occured. - */ - fluid_sfont_t* (*load)(fluid_sfloader_t* loader, const char* filename); +enum fluid_sample_type +{ + FLUID_SAMPLETYPE_MONO = 0x1, /**< Used for mono samples */ + FLUID_SAMPLETYPE_RIGHT = 0x2, /**< Used for right samples of a stereo pair */ + FLUID_SAMPLETYPE_LEFT = 0x4, /**< Used for left samples of a stereo pair */ + FLUID_SAMPLETYPE_LINKED = 0x8, /**< Currently not used */ + FLUID_SAMPLETYPE_OGG_VORBIS = 0x10, /**< Used for Ogg Vorbis compressed samples @since 1.1.7 */ + FLUID_SAMPLETYPE_ROM = 0x8000 /**< Indicates ROM samples, causes sample to be ignored */ }; + /** - * Virtual SoundFont instance structure. + * Method to load an instrument file (does not actually need to be a real file name, + * could be another type of string identifier that the \a loader understands). + * @param loader SoundFont loader + * @param filename File name or other string identifier + * @return The loaded instrument file (SoundFont) or NULL if an error occured. */ -struct _fluid_sfont_t { - void* data; /**< User defined data */ - unsigned int id; /**< SoundFont ID */ - - /** - * Method to free a virtual SoundFont bank. - * @param sfont Virtual SoundFont to free. - * @return Should return 0 when it was able to free all resources or non-zero - * if some of the samples could not be freed because they are still in use, - * in which case the free will be tried again later, until success. - */ - int (*free)(fluid_sfont_t* sfont); - - /** - * Method to return the name of a virtual SoundFont. - * @param sfont Virtual SoundFont - * @return The name of the virtual SoundFont. - */ - char* (*get_name)(fluid_sfont_t* sfont); - - /** - * Get a virtual SoundFont preset by bank and program numbers. - * @param sfont Virtual SoundFont - * @param bank MIDI bank number (0-16384) - * @param prenum MIDI preset number (0-127) - * @return Should return an allocated virtual preset or NULL if it could not - * be found. - */ - fluid_preset_t* (*get_preset)(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum); - - /** - * Start virtual SoundFont preset iteration method. - * @param sfont Virtual SoundFont - * - * Starts/re-starts virtual preset iteration in a SoundFont. - */ - void (*iteration_start)(fluid_sfont_t* sfont); - - /** - * Virtual SoundFont preset iteration function. - * @param sfont Virtual SoundFont - * @param preset Caller supplied preset 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. - */ - int (*iteration_next)(fluid_sfont_t* sfont, fluid_preset_t* preset); -}; +typedef fluid_sfont_t *(*fluid_sfloader_load_t)(fluid_sfloader_t *loader, const char *filename); + +/** + * The free method should free the memory allocated for a fluid_sfloader_t instance in + * addition to any private data. Any custom user provided cleanup function must ultimately call + * delete_fluid_sfloader() to ensure proper cleanup of the #fluid_sfloader_t struct. If no private data + * needs to be freed, setting this to delete_fluid_sfloader() is sufficient. + * @param loader SoundFont loader + */ +typedef void (*fluid_sfloader_free_t)(fluid_sfloader_t *loader); + + +FLUIDSYNTH_API fluid_sfloader_t *new_fluid_sfloader(fluid_sfloader_load_t load, fluid_sfloader_free_t free); +FLUIDSYNTH_API void delete_fluid_sfloader(fluid_sfloader_t *loader); -#define fluid_sfont_get_id(_sf) ((_sf)->id) +FLUIDSYNTH_API fluid_sfloader_t *new_fluid_defsfloader(fluid_settings_t *settings); /** - * Virtual SoundFont preset. + * Opens the file or memory indicated by \c filename in binary read mode. + * \c filename matches the string provided during the fluid_synth_sfload() call. + * + * @return returns a file handle on success, NULL otherwise */ -struct _fluid_preset_t { - void* data; /**< User supplied data */ - fluid_sfont_t* sfont; /**< Parent virtual SoundFont */ - - /** - * Method to free a virtual SoundFont preset. - * @param preset Virtual SoundFont preset - * @return Should return 0 - */ - int (*free)(fluid_preset_t* preset); - - /** - * Method to get a virtual SoundFont preset name. - * @param preset Virtual SoundFont preset - * @return Should return the name of the preset. The returned string must be - * valid for the duration of the virtual preset (or the duration of the - * SoundFont, in the case of preset iteration). - */ - char* (*get_name)(fluid_preset_t* preset); - - /** - * Method to get a virtual SoundFont preset MIDI bank number. - * @param preset Virtual SoundFont preset - * @param return The bank number of the preset - */ - int (*get_banknum)(fluid_preset_t* preset); - - /** - * Method to get a virtual SoundFont preset MIDI program number. - * @param preset Virtual SoundFont preset - * @param return The program number of the preset - */ - int (*get_num)(fluid_preset_t* preset); - - /** - * Method to handle a noteon event (synthesize the instrument). - * @param preset Virtual SoundFont preset - * @param synth Synthesizer instance - * @param chan MIDI channel number of the note on event - * @param key MIDI note number (0-127) - * @param vel MIDI velocity (0-127) - * @return #FLUID_OK on success (0) or #FLUID_FAILED (-1) otherwise - * - * This method may be called from within synthesis context and therefore - * should be as efficient as possible and not perform any operations considered - * bad for realtime audio output (memory allocations and other OS calls). - * - * 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_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 - * start playing the synthesis voice. Starting with FluidSynth 1.1.0 all voices - * created will be started at the same time. - */ - int (*noteon)(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel); - - /** - * Virtual SoundFont preset notify method. - * @param preset Virtual SoundFont preset - * @param reason #FLUID_PRESET_SELECTED or #FLUID_PRESET_UNSELECTED - * @param chan MIDI channel number - * @return Should return #FLUID_OK - * - * Implement this optional method if the preset needs to be notified about - * preset select and unselect events. - * - * This method may be called from within synthesis context and therefore - * should be as efficient as possible and not perform any operations considered - * bad for realtime audio output (memory allocations and other OS calls). - */ - int (*notify)(fluid_preset_t* preset, int reason, int chan); -}; +typedef void *(* fluid_sfloader_callback_open_t)(const char *filename); /** - * Virtual SoundFont sample. + * Reads \c count bytes to the specified buffer \c buf. + * + * @return returns #FLUID_OK if exactly \c count bytes were successfully read, else returns #FLUID_FAILED and leaves \a buf unmodified. */ -struct _fluid_sample_t -{ - char name[21]; /**< Sample name */ - unsigned int start; /**< Start index */ - unsigned int end; /**< End index, index of last valid sample point (contrary to SF spec) */ - unsigned int loopstart; /**< Loop start index */ - unsigned int loopend; /**< Loop end index, first point following the loop (superimposed on loopstart) */ - unsigned int samplerate; /**< Sample rate */ - int origpitch; /**< Original pitch (MIDI note number, 0-127) */ - int pitchadj; /**< Fine pitch adjustment (+/- 99 cents) */ - int sampletype; /**< Values: #FLUID_SAMPLETYPE_MONO, FLUID_SAMPLETYPE_RIGHT, FLUID_SAMPLETYPE_LEFT, FLUID_SAMPLETYPE_ROM */ - int valid; /**< Should be TRUE if sample data is valid, FALSE otherwise (in which case it will not be synthesized) */ - short* data; /**< Pointer to the sample's data */ - - int amplitude_that_reaches_noise_floor_is_valid; /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */ - double amplitude_that_reaches_noise_floor; /**< The amplitude at which the sample's loop will be below the noise floor. For voice off optimization, calculated automatically. */ - - unsigned int refcount; /**< Count of voices using this sample (use #fluid_sample_refcount to access this field) */ - - /** - * Implement this function to receive notification when sample is no longer used. - * @param sample Virtual SoundFont sample - * @param reason #FLUID_SAMPLE_DONE only currently - * @return Should return #FLUID_OK - */ - int (*notify)(fluid_sample_t* sample, int reason); - - void* userdata; /**< User defined data */ -}; +typedef int (* fluid_sfloader_callback_read_t)(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 + */ +typedef int (* fluid_sfloader_callback_seek_t)(void *handle, long offset, int origin); + +/** + * Closes the handle returned by #fluid_sfloader_callback_open_t and frees used ressources. + * + * @return returns #FLUID_OK on success, #FLUID_FAILED on error + */ +typedef int (* fluid_sfloader_callback_close_t)(void *handle); + +/** @return returns current file offset or #FLUID_FAILED on error */ +typedef long (* fluid_sfloader_callback_tell_t)(void *handle); + + +FLUIDSYNTH_API int fluid_sfloader_set_callbacks(fluid_sfloader_t *loader, + fluid_sfloader_callback_open_t open, + fluid_sfloader_callback_read_t read, + fluid_sfloader_callback_seek_t seek, + fluid_sfloader_callback_tell_t tell, + fluid_sfloader_callback_close_t close); + +FLUIDSYNTH_API int fluid_sfloader_set_data(fluid_sfloader_t *loader, void *data); +FLUIDSYNTH_API void *fluid_sfloader_get_data(fluid_sfloader_t *loader); + + + +/** + * Method to return the name of a virtual SoundFont. + * @param sfont Virtual SoundFont + * @return The name of the virtual SoundFont. + */ +typedef const char *(*fluid_sfont_get_name_t)(fluid_sfont_t *sfont); + +/** + * Get a virtual SoundFont preset by bank and program numbers. + * @param sfont Virtual SoundFont + * @param bank MIDI bank number (0-16383) + * @param prenum MIDI preset number (0-127) + * @return Should return an allocated virtual preset or NULL if it could not + * be found. + */ +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 + * needs to be freed, setting this to delete_fluid_sfont() is sufficient. + * @param sfont Virtual SoundFont to free. + * @return Should return 0 when it was able to free all resources or non-zero + * if some of the samples could not be freed because they are still in use, + * in which case the free will be tried again later, until success. + */ +typedef int (*fluid_sfont_free_t)(fluid_sfont_t *sfont); -#define fluid_sample_refcount(_sample) ((_sample)->refcount) /**< Get the reference count of a sample. Should only be called from within synthesis context (noteon method for example) */ +FLUIDSYNTH_API 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); +FLUIDSYNTH_API int delete_fluid_sfont(fluid_sfont_t *sfont); -#define FLUID_SAMPLETYPE_MONO 1 /**< Flag for #fluid_sample_t \a sampletype field for mono samples */ -#define FLUID_SAMPLETYPE_RIGHT 2 /**< Flag for #fluid_sample_t \a sampletype field for right samples of a stereo pair */ -#define FLUID_SAMPLETYPE_LEFT 4 /**< Flag for #fluid_sample_t \a sampletype field for left samples of a stereo pair */ -#define FLUID_SAMPLETYPE_LINKED 8 /**< Flag for #fluid_sample_t \a sampletype field, not used currently */ -#define FLUID_SAMPLETYPE_ROM 0x8000 /**< Flag for #fluid_sample_t \a sampletype field, ROM sample, causes sample to be ignored */ +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. + * @param preset Virtual SoundFont preset + * @return Should return the name of the preset. The returned string must be + * valid for the duration of the virtual preset (or the duration of the + * SoundFont, in the case of preset iteration). + */ +typedef const char *(*fluid_preset_get_name_t)(fluid_preset_t *preset); + +/** + * Method to get a virtual SoundFont preset MIDI bank number. + * @param preset Virtual SoundFont preset + * @param return The bank number of the preset + */ +typedef int (*fluid_preset_get_banknum_t)(fluid_preset_t *preset); + +/** + * Method to get a virtual SoundFont preset MIDI program number. + * @param preset Virtual SoundFont preset + * @param return The program number of the preset + */ +typedef int (*fluid_preset_get_num_t)(fluid_preset_t *preset); + +/** + * Method to handle a noteon event (synthesize the instrument). + * @param preset Virtual SoundFont preset + * @param synth Synthesizer instance + * @param chan MIDI channel number of the note on event + * @param key MIDI note number (0-127) + * @param vel MIDI velocity (0-127) + * @return #FLUID_OK on success (0) or #FLUID_FAILED (-1) otherwise + * + * This method may be called from within synthesis context and therefore + * should be as efficient as possible and not perform any operations considered + * bad for realtime audio output (memory allocations and other OS calls). + * + * 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_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 + * start playing the synthesis voice. Starting with FluidSynth 1.1.0 all voices + * created will be started at the same time. + */ +typedef int (*fluid_preset_noteon_t)(fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel); + +/** + * Method to free a virtual SoundFont preset. Any custom user provided cleanup function must ultimately call + * delete_fluid_preset() to ensure proper cleanup of the #fluid_preset_t struct. If no private data + * needs to be freed, setting this to delete_fluid_preset() is sufficient. + * @param preset Virtual SoundFont preset + * @return Should return 0 + */ +typedef void (*fluid_preset_free_t)(fluid_preset_t *preset); + +FLUIDSYNTH_API fluid_preset_t *new_fluid_preset(fluid_sfont_t *parent_sfont, + fluid_preset_get_name_t get_name, + fluid_preset_get_banknum_t get_bank, + fluid_preset_get_num_t get_num, + fluid_preset_noteon_t noteon, + fluid_preset_free_t free); +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_sfont_t *fluid_preset_get_sfont(fluid_preset_t *preset); + +FLUIDSYNTH_API fluid_sample_t *new_fluid_sample(void); +FLUIDSYNTH_API void delete_fluid_sample(fluid_sample_t *sample); +FLUIDSYNTH_API size_t fluid_sample_sizeof(void); + +FLUIDSYNTH_API int fluid_sample_set_name(fluid_sample_t *sample, const char *name); +FLUIDSYNTH_API int fluid_sample_set_sound_data(fluid_sample_t *sample, + short *data, + char *data24, + unsigned int nbframes, + unsigned int sample_rate, + short copy_data); + +FLUIDSYNTH_API int fluid_sample_set_loop(fluid_sample_t *sample, unsigned int loop_start, unsigned int loop_end); +FLUIDSYNTH_API int fluid_sample_set_pitch(fluid_sample_t *sample, int root_key, int fine_tune); #ifdef __cplusplus } |