2021-04-20 20:09:02 +00:00
/* FluidSynth - A Software Synthesizer
*
* Copyright ( C ) 2003 Peter Hanappe and others .
*
* This library is free software ; you can redistribute it and / or
2022-04-18 12:49:11 +00:00
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation ; either version 2.1 of
2021-04-20 20:09:02 +00:00
* 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
2022-04-18 12:49:11 +00:00
* Lesser General Public License for more details .
2021-04-20 20:09:02 +00:00
*
2022-04-18 12:49:11 +00:00
* You should have received a copy of the GNU Lesser General Public
2021-04-20 20:09:02 +00:00
* License along with this library ; if not , write to the Free
* Software Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA
* 02110 - 1301 , USA
*/
# ifndef _FLUIDSYNTH_SFONT_H
# define _FLUIDSYNTH_SFONT_H
# ifdef __cplusplus
extern " C " {
# endif
/**
* @ file sfont . h
* @ 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
* 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 .
*
* 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 .
*
* The # fluid_preset_t structure contains some functions to obtain
* information from the preset ( name , bank , number ) . The most
* important callback is the noteon function . The noteon function
* 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_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 .
*/
/**
* 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 */
} ;
/**
* SoundFont loader structure .
*/
struct _fluid_sfloader_t {
2022-04-18 12:49:11 +00:00
void * data ; /**< User defined data pointer used by _fluid_sfloader_t::load() */
2021-04-20 20:09:02 +00:00
/**
* 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 ) ;
} ;
/**
* Virtual SoundFont instance structure .
*/
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
2022-04-18 12:49:11 +00:00
* @ param bank MIDI bank number ( 0 - 16383 )
2021-04-20 20:09:02 +00:00
* @ 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 ) ;
} ;
# define fluid_sfont_get_id(_sf) ((_sf)->id)
/**
* Virtual SoundFont preset .
*/
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 ) ;
} ;
/**
* Virtual SoundFont sample .
*/
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 */
} ;
# 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) */
# 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 */
2022-04-18 12:49:11 +00:00
# define FLUID_SAMPLETYPE_OGG_VORBIS 0x10 /**< Flag for #fluid_sample_t \a sampletype field for Ogg Vorbis compressed samples @since 1.1.7 */
2021-04-20 20:09:02 +00:00
# define FLUID_SAMPLETYPE_ROM 0x8000 /**< Flag for #fluid_sample_t \a sampletype field, ROM sample, causes sample to be ignored */
# ifdef __cplusplus
}
# endif
# endif /* _FLUIDSYNTH_SFONT_H */