diff options
Diffstat (limited to 'libs/fluidsynth/fluidsynth/sfont.h')
-rw-r--r-- | libs/fluidsynth/fluidsynth/sfont.h | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/libs/fluidsynth/fluidsynth/sfont.h b/libs/fluidsynth/fluidsynth/sfont.h new file mode 100644 index 0000000000..30aebfd126 --- /dev/null +++ b/libs/fluidsynth/fluidsynth/sfont.h @@ -0,0 +1,281 @@ +/* FluidSynth - A Software Synthesizer + * + * 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 + * 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 + * 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 { + 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); +}; + +/** + * 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 + * @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); +}; + +#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 */ +#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 */ |