Added correct spelling of FLUID_SEQ_PITCHWHEELSENS with backwards compatible misspelled symbol.

Added FLUID_OK and FLUID_FAILED to public API (misc.h).
Renamed parameter of new_fluid_sequencer2() to use_system_timer.
Renamed fludi_sequencer_get_useSystemTimer() to fluid_sequencer_get_use_system_timer().
Added missing FLUIDSYNTH_API to fluid_sequencer_add_midi_event_to_buffer().
Declared many local functions as static.
Changed settings in doc/Doxyfile to only extract public documentation.
Tons and tons of documentation updates on public API.
This commit is contained in:
Josh Green 2009-10-15 07:00:30 +00:00
parent 76777760ce
commit 420ba8198f
36 changed files with 1188 additions and 966 deletions

View file

@ -50,7 +50,7 @@ TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = NO
@ -95,43 +95,11 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
INPUT = fluidsynth-v11-devdoc.txt \
../include \
../include/fluidsynth \
../src
INPUT_ENCODING = UTF-8
FILE_PATTERNS = fluidsynth.h \
audio.h \
event.h \
gen.h \
log.h \
midi.h \
misc.h \
mod.h \
ramsfont.h \
seq.h \
seqbind.h \
settings.h \
sfont.h \
shell.h \
synth.h \
types.h \
version.h \
voice.h \
fluid_adriver.c \
fluid_cmd.c \
fluid_event.c \
fluid_filerenderer.c \
fluid_gen.c \
fluid_sys.c \
fluid_mdriver.c \
fluid_midi.* \
fluid_midi_router.* \
fluid_mod.c \
fluid_ramsfont.c \
fluid_seq.c \
fluid_seqbind.c \
fluid_settings.c \
fluid_synth.c \
fluid_voice.c
RECURSIVE = YES
FILE_PATTERNS = *.[ch]
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
@ -146,7 +114,7 @@ FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO

View file

@ -37,7 +37,6 @@ extern "C" {
* audio driver (although it is not as efficient).
*
* @sa @ref CreatingAudioDriver
* @{
*/
/**
@ -47,7 +46,7 @@ extern "C" {
* @param data The user data parameter as passed to new_fluid_audio_driver2().
* @param len Length of the audio in frames.
* @param nin Count of buffers in 'in'
* @param in FIXME - Not used currently?
* @param in Not used currently
* @param nout Count of arrays in 'out' (i.e., channel count)
* @param out Output buffers, one for each channel
* @return Should return 0 on success, non-zero if an error occured.
@ -78,6 +77,4 @@ FLUIDSYNTH_API const char **fluid_file_renderer_get_endian_names (void);
}
#endif
/** @} */
#endif /* _FLUIDSYNTH_AUDIO_H */

View file

@ -36,7 +36,7 @@ extern "C" {
* Sequencer event type enumeration.
*/
enum fluid_seq_event_type {
FLUID_SEQ_NOTE = 0, /**< Note event (DOCME) */
FLUID_SEQ_NOTE = 0, /**< Note event with duration */
FLUID_SEQ_NOTEON, /**< Note on event */
FLUID_SEQ_NOTEOFF, /**< Note off event */
FLUID_SEQ_ALLSOUNDSOFF, /**< All sounds off event */
@ -45,7 +45,7 @@ enum fluid_seq_event_type {
FLUID_SEQ_PROGRAMCHANGE, /**< Program change message */
FLUID_SEQ_PROGRAMSELECT, /**< Program select message (DOCME) */
FLUID_SEQ_PITCHBEND, /**< Pitch bend message */
FLUID_SEQ_PITCHWHHELSENS, /**< Pitch wheel sensitivity set message TODO: Correct spelling of this event? */
FLUID_SEQ_PITCHWHEELSENS, /**< Pitch wheel sensitivity set message @since 1.1.0 was mispelled previously */
FLUID_SEQ_MODULATION, /**< Modulation controller event */
FLUID_SEQ_SUSTAIN, /**< Sustain controller event */
FLUID_SEQ_CONTROLCHANGE, /**< MIDI control change event */
@ -61,6 +61,8 @@ enum fluid_seq_event_type {
FLUID_SEQ_LASTEVENT /**< Defines the count of event enums */
};
#define FLUID_SEQ_PITCHWHHELSENS FLUID_SEQ_PITCHWHEELSENS /**< Old deprecated misspelling of #FLUID_SEQ_PITCHWHEELSENS */
/* Event alloc/free */
FLUIDSYNTH_API fluid_event_t* new_fluid_event(void);
FLUIDSYNTH_API void delete_fluid_event(fluid_event_t* evt);

View file

@ -115,13 +115,13 @@ typedef struct _fluid_gen_t
} fluid_gen_t;
/**
* Enum value for 'flags' field of #_fluid_gen_t (not really flags).
* Enum value for 'flags' field of #fluid_gen_t (not really flags).
*/
enum fluid_gen_flags
{
GEN_UNUSED, /**< Generator value is not set */
GEN_SET, /**< Generator value is set */
GEN_ABS_NRPN /**< DOCME */
GEN_ABS_NRPN /**< Generator is an absolute value */
};
FLUIDSYNTH_API int fluid_gen_set_default_values(fluid_gen_t* gen);

View file

@ -41,11 +41,12 @@ extern "C" {
* and ignores all other messages by setting the log function to
* NULL:
*
* DOCME (formatting)
* fluid_set_log_function(FLUID_PANIC, show_dialog, (void*) root_window);
* fluid_set_log_function(FLUID_ERR, NULL, NULL);
* fluid_set_log_function(FLUID_WARN, NULL, NULL);
* fluid_set_log_function(FLUID_DBG, NULL, NULL);
* @code
* fluid_set_log_function(FLUID_PANIC, show_dialog, (void*) root_window);
* fluid_set_log_function(FLUID_ERR, NULL, NULL);
* fluid_set_log_function(FLUID_WARN, NULL, NULL);
* fluid_set_log_function(FLUID_DBG, NULL, NULL);
* @endcode
*/
/**

View file

@ -56,7 +56,7 @@ FLUIDSYNTH_API int fluid_midi_event_set_sysex(fluid_midi_event_t* evt, void *dat
* Generic callback function for MIDI events.
* @param data User defined data pointer
* @param event The MIDI event
* @return DOCME
* @return Should return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* Will be used between
* - MIDI driver and MIDI router
@ -66,26 +66,14 @@ FLUIDSYNTH_API int fluid_midi_event_set_sysex(fluid_midi_event_t* evt, void *dat
*/
typedef int (*handle_midi_event_func_t)(void* data, fluid_midi_event_t* event);
/*
* MIDI router
*
* The MIDI handler forwards incoming MIDI events to the synthesizer
*/
FLUIDSYNTH_API fluid_midi_router_t* new_fluid_midi_router(fluid_settings_t* settings,
handle_midi_event_func_t handler,
void* event_handler_data);
FLUIDSYNTH_API int delete_fluid_midi_router(fluid_midi_router_t* handler);
FLUIDSYNTH_API int fluid_midi_router_handle_midi_event(void* data, fluid_midi_event_t* event);
FLUIDSYNTH_API int fluid_midi_dump_prerouter(void* data, fluid_midi_event_t* event);
FLUIDSYNTH_API int fluid_midi_dump_postrouter(void* data, fluid_midi_event_t* event);
/*
* MIDI driver
*
* The MIDI handler forwards incoming MIDI events to the synthesizer
*/
FLUIDSYNTH_API
fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings,
@ -97,17 +85,14 @@ FLUIDSYNTH_API void delete_fluid_midi_driver(fluid_midi_driver_t* driver);
FLUIDSYNTH_API void fluid_midi_driver_get_names(char* buf, size_t buflen, const char* separator);
/*
* MIDI file player
*
* The MIDI player allows you to play MIDI files with the FLUID Synth
/**
* MIDI player status enum.
*/
enum fluid_player_status
{
FLUID_PLAYER_READY,
FLUID_PLAYER_PLAYING,
FLUID_PLAYER_DONE
FLUID_PLAYER_READY, /**< Player is ready */
FLUID_PLAYER_PLAYING, /**< Player is currently playing */
FLUID_PLAYER_DONE /**< Player is finished playing */
};
FLUIDSYNTH_API fluid_player_t* new_fluid_player(fluid_synth_t* synth);

View file

@ -27,32 +27,44 @@ extern "C" {
#endif
/*
/**
* @file misc.h
* @brief Miscellaneous utility functions and defines
*/
/**
* Value that indicates success, used by most libfluidsynth functions.
* @since 1.1.0
*
* Utility functions
* NOTE: This was not publicly defined prior to libfluidsynth 1.1.0. When
* writing code which should also be compatible with older versions, something
* like the following can be used:
*
* @code
* #include <fluidsynth.h>
*
* #ifndef FLUID_OK
* #define FLUID_OK (0)
* #define FLUID_FAILED (-1)
* #endif
* @endcode
*/
#define FLUID_OK (0)
/**
* fluid_is_soundfont returns 1 if the specified filename is a
* soundfont. It retuns 0 otherwise. The current implementation only
* checks for the "RIFF" header in the file. It is useful only to
* distinguish between SoundFonts and MIDI files.
* Value that indicates failure, used by most libfluidsynth functions.
* @since 1.1.0
*
* NOTE: See #FLUID_OK for more details.
*/
#define FLUID_FAILED (-1)
FLUIDSYNTH_API int fluid_is_soundfont(char* filename);
/**
* fluid_is_midifile returns 1 if the specified filename is a MIDI
* file. It retuns 0 otherwise. The current implementation only checks
* for the "MThd" header in the file.
*/
FLUIDSYNTH_API int fluid_is_midifile(char* filename);
#ifdef WIN32
/** Set the handle to the instance of the application on the Windows
platform. The handle is needed to open DirectSound. */
FLUIDSYNTH_API void* fluid_get_hinstance(void);
FLUIDSYNTH_API void fluid_set_hinstance(void* hinstance);
#endif

View file

@ -25,22 +25,24 @@
extern "C" {
#endif
/* Modulator-related definitions */
/**
* @file mod.h
* @brief SoundFont modulator functions and constants.
*/
/* Maximum number of modulators in a voice */
#define FLUID_NUM_MOD 64
#define FLUID_NUM_MOD 64 /**< Maximum number of modulators in a voice */
/*
* fluid_mod_t
*/
/**
* Modulator structure. See SoundFont 2.04 PDF section 8.2.
*/
struct _fluid_mod_t
{
unsigned char dest;
unsigned char src1;
unsigned char flags1;
unsigned char src2;
unsigned char flags2;
double amount;
unsigned char dest; /**< Destination generator to control */
unsigned char src1; /**< Source controller 1 */
unsigned char flags1; /**< Source controller 1 flags */
unsigned char src2; /**< Source controller 2 */
unsigned char flags2; /**< Source controller 2 flags */
double amount; /**< Multiplier amount */
/* The 'next' field allows to link modulators into a list. It is
* not used in fluid_voice.c, there each voice allocates memory for a
* fixed number of modulators. Since there may be a huge number of
@ -49,44 +51,45 @@ struct _fluid_mod_t
fluid_mod_t * next;
};
/* Flags telling the polarity of a modulator. Compare with SF2.01
section 8.2. Note: The numbers of the bits are different! (for
example: in the flags of a SF modulator, the polarity bit is bit
nr. 9) */
/**
* Flags defining the polarity and mapping function of a modulator source.
* Compare with SoundFont 2.04 PDF section 8.2.
*
* Note: The numbers of the bits are different! (for example: in the flags of
* a SoundFont modulator, the polarity bit is bit #9).
*/
enum fluid_mod_flags
{
FLUID_MOD_POSITIVE = 0,
FLUID_MOD_NEGATIVE = 1,
FLUID_MOD_UNIPOLAR = 0,
FLUID_MOD_BIPOLAR = 2,
FLUID_MOD_LINEAR = 0,
FLUID_MOD_CONCAVE = 4,
FLUID_MOD_CONVEX = 8,
FLUID_MOD_SWITCH = 12,
FLUID_MOD_GC = 0,
FLUID_MOD_CC = 16
FLUID_MOD_POSITIVE = 0, /**< Mapping function is positive */
FLUID_MOD_NEGATIVE = 1, /**< Mapping function is negative */
FLUID_MOD_UNIPOLAR = 0, /**< Mapping function is unipolar */
FLUID_MOD_BIPOLAR = 2, /**< Mapping function is bipolar */
FLUID_MOD_LINEAR = 0, /**< Linear mapping function */
FLUID_MOD_CONCAVE = 4, /**< Concave mapping function */
FLUID_MOD_CONVEX = 8, /**< Convex mapping function */
FLUID_MOD_SWITCH = 12, /**< Switch (on/off) mapping function */
FLUID_MOD_GC = 0, /**< General controller */
FLUID_MOD_CC = 16 /**< MIDI CC controller */
};
/* Flags telling the source of a modulator. This corresponds to
* SF2.01 section 8.2.1 */
/**
* Flags indicating the source of a modulator (if #FLUID_MOD_GC). This
* corresponds to SoundFont 2.04 PDF section 8.2.1
*/
enum fluid_mod_src
{
FLUID_MOD_NONE = 0,
FLUID_MOD_VELOCITY = 2,
FLUID_MOD_KEY = 3,
FLUID_MOD_KEYPRESSURE = 10,
FLUID_MOD_CHANNELPRESSURE = 13,
FLUID_MOD_PITCHWHEEL = 14,
FLUID_MOD_PITCHWHEELSENS = 16
FLUID_MOD_NONE = 0, /**< No source controller */
FLUID_MOD_VELOCITY = 2, /**< MIDI note-on velocity */
FLUID_MOD_KEY = 3, /**< MIDI note-on note number */
FLUID_MOD_KEYPRESSURE = 10, /**< MIDI key pressure */
FLUID_MOD_CHANNELPRESSURE = 13, /**< MIDI channel pressure */
FLUID_MOD_PITCHWHEEL = 14, /**< Pitch wheel */
FLUID_MOD_PITCHWHEELSENS = 16 /**< Pitch wheel sensitivity */
};
/* Allocates memory for a new modulator */
FLUIDSYNTH_API fluid_mod_t * fluid_mod_new(void);
/* Frees the modulator */
FLUIDSYNTH_API fluid_mod_t* fluid_mod_new(void);
FLUIDSYNTH_API void fluid_mod_delete(fluid_mod_t * mod);
FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t* mod, int src, int flags);
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t* mod, int src, int flags);
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t* mod, int dst);
@ -99,9 +102,6 @@ FLUIDSYNTH_API int fluid_mod_get_flags2(fluid_mod_t* mod);
FLUIDSYNTH_API int fluid_mod_get_dest(fluid_mod_t* mod);
FLUIDSYNTH_API double fluid_mod_get_amount(fluid_mod_t* mod);
/* Determines, if two modulators are 'identical' (all parameters
except the amount match) */
FLUIDSYNTH_API int fluid_mod_test_identity(fluid_mod_t * mod1, fluid_mod_t * mod2);

View file

@ -18,6 +18,8 @@
* 02111-1307, USA
*/
/* RAM SoundFonts: October 2002 - Antoine Schmitt */
#ifndef _FLUIDSYNTH_RAMSFONT_H
#define _FLUIDSYNTH_RAMSFONT_H
@ -25,82 +27,39 @@
extern "C" {
#endif
/********************************************************************************/
/********************************************************************************/
/* ram soundfonts:
October 2002 - Antoine Schmitt
ram soundfonts live in ram. The samples are loaded from files
or from RAM. A minimal API manages a soundFont structure,
with presets, each preset having only one preset-zone, which
instrument has potentially many instrument-zones. No global
zones, and nor generator nor modulator other than the default
ones are permitted. This may be extensible in the future.
*/
/********************************************************************************/
/********************************************************************************/
/*
We are not using the sfloader protocol, as we need more arguments
than what it provides.
*/
/** Creates a fluid_sfont_t wrapping an fluid_ramsfont_t */
FLUIDSYNTH_API fluid_sfont_t* fluid_ramsfont_create_sfont(void);
/***********************
* ramsfont specific API
***********************/
FLUIDSYNTH_API int fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, char * name);
/* Creates one instrument zone for the sample inside the preset defined
* by bank/num
* \returns 0 if success
/**
* @file ramsfont.h
* @brief API for creating and managing SoundFont instruments in RAM.
*
* RAM SoundFonts live in ram. The samples are loaded from files
* or from RAM. A minimal API manages a soundFont structure,
* with presets, each preset having only one preset-zone, which
* instrument has potentially many instrument-zones. No global
* zones, and nor generator nor modulator other than the default
* ones are permitted. This may be extensible in the future.
*/
FLUIDSYNTH_API fluid_sfont_t* fluid_ramsfont_create_sfont(void);
FLUIDSYNTH_API int fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, char * name);
FLUIDSYNTH_API
int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int lokey, int hikey);
/* Removes the instrument zone corresponding to bank/num and to the sample
* \returns 0 if success
*/
FLUIDSYNTH_API
int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample);
/* Sets a generator on an instrument zone
* \returns 0 if success
*/
FLUIDSYNTH_API
int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int gen_type, float value);
/* Utility : sets the loop start/end values
* \on = 0 or 1; if 0, loopstart and loopend are not used
* \loopstart and loopend are floats, in frames
* \loopstart is counted from frame 0
* \loopend is counted from the last frame, thus is < 0
* \returns 0 if success
*/
FLUIDSYNTH_API
int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int on, float loopstart, float loopend);
/***************************************
* sample_t specific API for ramsfont
***************************************/
FLUIDSYNTH_API fluid_sample_t* new_fluid_ramsample(void);
FLUIDSYNTH_API int delete_fluid_ramsample(fluid_sample_t* sample);
FLUIDSYNTH_API int fluid_sample_set_name(fluid_sample_t* sample, char * name);
/* Sets the sound data of the sample
* Warning : if copy_data is FALSE, data should have 8 unused frames at start
* and 8 unused frames at the end.
*/
FLUIDSYNTH_API
int fluid_sample_set_sound_data(fluid_sample_t* sample, short *data,
unsigned int nbframes, short copy_data, int rootkey);

View file

@ -25,81 +25,39 @@
extern "C" {
#endif
/**
* @file seq.h
* @brief MIDI event sequencer.
*/
typedef void (*fluid_event_callback_t)(unsigned int time, fluid_event_t* event,
fluid_sequencer_t* seq, void* data);
/** Allocate a new sequencer structure */
FLUIDSYNTH_API fluid_sequencer_t* new_fluid_sequencer(void);
FLUIDSYNTH_API fluid_sequencer_t* new_fluid_sequencer2(int useSystemTimer);
/** Free the sequencer structure */
FLUIDSYNTH_API fluid_sequencer_t* new_fluid_sequencer2(int use_system_timer);
FLUIDSYNTH_API void delete_fluid_sequencer(fluid_sequencer_t* seq);
FLUIDSYNTH_API int fluid_sequencer_get_useSystemTimer(fluid_sequencer_t* seq);
/** clients can be sources or destinations of events. These functions ensure a unique ID for any
source or dest, for filtering purposes.
sources only dont need to register a callback.
*/
/** Register a client. The registration returns a unique client ID (-1 if error) */
FLUIDSYNTH_API int fluid_sequencer_get_use_system_timer(fluid_sequencer_t* seq);
FLUIDSYNTH_API
short fluid_sequencer_register_client(fluid_sequencer_t* seq, char* name,
fluid_event_callback_t callback, void* data);
/** Unregister a previously registered client. */
FLUIDSYNTH_API void fluid_sequencer_unregister_client(fluid_sequencer_t* seq, short id);
/** Returns the number of register clients. */
FLUIDSYNTH_API int fluid_sequencer_count_clients(fluid_sequencer_t* seq);
/** Returns the id of a registered client (-1 if non existing) */
FLUIDSYNTH_API short fluid_sequencer_get_client_id(fluid_sequencer_t* seq, int index);
/** Returns the name of a registered client, given its id. */
FLUIDSYNTH_API char* fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id);
/** Returns 1 if client is a destination (has a callback) */
FLUIDSYNTH_API int fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id);
/** Advance sequencer. Do not use if you created the sequencer with useSystemTimer enabled. */
FLUIDSYNTH_API void fluid_sequencer_process(fluid_sequencer_t* seq, unsigned int msec);
/** Sending an event immediately. */
FLUIDSYNTH_API void fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt);
/** Schedule an event for later sending. If absolute is 0, the time of
the event will be offset with the current tick of the
sequencer. If absolute is different from 0, the time will assumed
to be absolute (starting from the creation of the sequencer).
MAKES A COPY */
FLUIDSYNTH_API
int fluid_sequencer_send_at(fluid_sequencer_t* seq, fluid_event_t* evt,
unsigned int time, int absolute);
/** Remove events from the event queue. The events can be filtered on
the source, the destination, and the type of the event. To avoid
filtering, set either source, dest, or type to -1. */
FLUIDSYNTH_API
void fluid_sequencer_remove_events(fluid_sequencer_t* seq, short source, short dest, int type);
/** Get the current tick */
FLUIDSYNTH_API unsigned int fluid_sequencer_get_tick(fluid_sequencer_t* seq);
/** Set the conversion from tick to absolute time. scale should be
expressed as ticks per second. */
FLUIDSYNTH_API void fluid_sequencer_set_time_scale(fluid_sequencer_t* seq, double scale);
/** Set the conversion from tick to absolute time (ticks per
second). */
FLUIDSYNTH_API double fluid_sequencer_get_time_scale(fluid_sequencer_t* seq);
// compile in internal traceing functions
// Compile in internal traceing functions
#define FLUID_SEQ_WITH_TRACE 0
#if FLUID_SEQ_WITH_TRACE

View file

@ -27,15 +27,14 @@
extern "C" {
#endif
/** registers fluidsynth as a client of the given sequencer.
The fluidsynth is registered with the name "fluidsynth".
\returns the fluidsynth destID.
*/
/**
* @file seqbind.h
* @brief FIXME Not sure why this is separate from seq.h.
*/
FLUIDSYNTH_API
short fluid_sequencer_register_fluidsynth(fluid_sequencer_t* seq, fluid_synth_t* synth);
int
FLUIDSYNTH_API int
fluid_sequencer_add_midi_event_to_buffer(void* data, fluid_midi_event_t* event);

View file

@ -49,15 +49,16 @@ extern "C" {
* }
* @endcode
* @sa @ref CreatingSettings
* @{
*/
/** Hint FLUID_HINT_BOUNDED_BELOW indicates that the LowerBound field
of the FLUID_PortRangeHint should be considered meaningful. The
value in this field should be considered the (inclusive) lower
bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
specified then the value of LowerBound should be multiplied by the
sample rate. */
/**
* Hint FLUID_HINT_BOUNDED_BELOW indicates that the LowerBound field
* of the FLUID_PortRangeHint should be considered meaningful. The
* value in this field should be considered the (inclusive) lower
* bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
* specified then the value of LowerBound should be multiplied by the
* sample rate.
*/
#define FLUID_HINT_BOUNDED_BELOW 0x1
/** Hint FLUID_HINT_BOUNDED_ABOVE indicates that the UpperBound field
@ -68,38 +69,45 @@ extern "C" {
sample rate. */
#define FLUID_HINT_BOUNDED_ABOVE 0x2
/** Hint FLUID_HINT_TOGGLED indicates that the data item should be
considered a Boolean toggle. Data less than or equal to zero should
be considered `off' or `false,' and data above zero should be
considered `on' or `true.' FLUID_HINT_TOGGLED may not be used in
conjunction with any other hint except FLUID_HINT_DEFAULT_0 or
FLUID_HINT_DEFAULT_1. */
/**
* Hint FLUID_HINT_TOGGLED indicates that the data item should be
* considered a Boolean toggle. Data less than or equal to zero should
* be considered `off' or `false,' and data above zero should be
* considered `on' or `true.' FLUID_HINT_TOGGLED may not be used in
* conjunction with any other hint.
*/
#define FLUID_HINT_TOGGLED 0x4
/** Hint FLUID_HINT_SAMPLE_RATE indicates that any bounds specified
should be interpreted as multiples of the sample rate. For
instance, a frequency range from 0Hz to the Nyquist frequency (half
the sample rate) could be requested by this hint in conjunction
with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds
at all must support this hint to retain meaning. */
/**
* Hint FLUID_HINT_SAMPLE_RATE indicates that any bounds specified
* should be interpreted as multiples of the sample rate. For
* instance, a frequency range from 0Hz to the Nyquist frequency (half
* the sample rate) could be requested by this hint in conjunction
* with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds
* at all must support this hint to retain meaning.
*/
#define FLUID_HINT_SAMPLE_RATE 0x8
/** Hint FLUID_HINT_LOGARITHMIC indicates that it is likely that the
user will find it more intuitive to view values using a logarithmic
scale. This is particularly useful for frequencies and gains. */
/**
* Hint FLUID_HINT_LOGARITHMIC indicates that it is likely that the
* user will find it more intuitive to view values using a logarithmic
* scale. This is particularly useful for frequencies and gains.
*/
#define FLUID_HINT_LOGARITHMIC 0x10
/** Hint FLUID_HINT_INTEGER indicates that a user interface would
probably wish to provide a stepped control taking only integer
values. Any bounds set should be slightly wider than the actual
integer range required to avoid floating point rounding errors. For
instance, the integer set {0,1,2,3} might be described as [-0.1,
3.1]. */
/**
* Hint FLUID_HINT_INTEGER indicates that a user interface would
* probably wish to provide a stepped control taking only integer
* values. Any bounds set should be slightly wider than the actual
* integer range required to avoid floating point rounding errors. For
* instance, the integer set {0,1,2,3} might be described as [-0.1,
* 3.1].
*/
#define FLUID_HINT_INTEGER 0x20
#define FLUID_HINT_FILENAME 0x01
#define FLUID_HINT_OPTIONLIST 0x02
#define FLUID_HINT_FILENAME 0x01 /**< Setting is a file name */
#define FLUID_HINT_OPTIONLIST 0x02 /**< Setting is a list of string options */
/**
@ -110,11 +118,11 @@ extern "C" {
* function fluid_settings_get_type()
*/
enum fluid_types_enum {
FLUID_NO_TYPE = -1,//!< Undefined type
FLUID_NUM_TYPE, //!< Numeric (double)
FLUID_INT_TYPE, //!< Integer
FLUID_STR_TYPE, //!< String
FLUID_SET_TYPE //!< Set of values
FLUID_NO_TYPE = -1, /**< Undefined type */
FLUID_NUM_TYPE, /**< Numeric (double) */
FLUID_INT_TYPE, /**< Integer */
FLUID_STR_TYPE, /**< String */
FLUID_SET_TYPE /**< Set of values */
};
@ -176,6 +184,9 @@ void fluid_settings_getint_range(fluid_settings_t* settings, char* name,
/**
* Callback function type used with fluid_settings_foreach_option()
* @param data User defined data pointer
* @param name Setting name
* @param option A string option for this setting (iterates through the list)
*/
typedef void (*fluid_settings_foreach_option_t)(void* data, char* name, char* option);
@ -192,8 +203,11 @@ int fluid_settings_option_count (fluid_settings_t* settings, char* name);
/**
* Callback function type used with fluid_settings_foreach()
* @param data User defined data pointer
* @param name Setting name
* @param type Setting type (#fluid_types_enum)
*/
typedef void (*fluid_settings_foreach_t)(void* data, char* s, int type);
typedef void (*fluid_settings_foreach_t)(void* data, char* name, int type);
FLUIDSYNTH_API
void fluid_settings_foreach(fluid_settings_t* settings, void* data,
@ -206,6 +220,4 @@ void fluid_settings_foreach_alpha(fluid_settings_t* settings, void* data,
}
#endif
/** @} */
#endif /* _FLUIDSYNTH_SETTINGS_H */

View file

@ -26,163 +26,252 @@ extern "C" {
#endif
/**
*
* 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.
*
* 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 an 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 increments the values of a
* generator, use fluid_voice_gen_{set,incr}. When you are
* finished initializing the voice call fluid_voice_start() to
* start playing the synthesis voice.
* */
enum {
FLUID_PRESET_SELECTED,
FLUID_PRESET_UNSELECTED,
FLUID_SAMPLE_DONE
};
/*
* fluid_sfloader_t
/**
* @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.
*/
struct _fluid_sfloader_t {
/** Private data */
void* data;
/** The free must free the memory allocated for the loader in
* addition to any private data. It should return 0 if no error
* occured, non-zero otherwise.*/
int (*free)(fluid_sfloader_t* loader);
/** Load a file. Returns NULL if an error occured. */
fluid_sfont_t* (*load)(fluid_sfloader_t* loader, const char* filename);
/**
* 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 */
};
/*
* fluid_sfont_t
/**
* 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;
unsigned int id;
void* data; /**< User defined data */
unsigned int id; /**< SoundFont ID */
/** The 'free' callback function should return 0 when it was able to
free all resources. It should return a non-zero value if some of
the samples could not be freed because they are still in use. */
/**
* 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);
/** Return the name of the 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);
/** Return the preset with the specified bank and preset number. All
* the fields, including the 'sfont' field, should * be filled
* in. If the preset cannot be found, the function returns NULL. */
/**
* 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);
/* return 0 when no more presets are available, 1 otherwise */
/**
* 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)
/*
* fluid_preset_t
/**
* Virtual SoundFont preset.
*/
struct _fluid_preset_t {
void* data;
fluid_sfont_t* sfont;
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);
/** handle a noteon event. Returns 0 if no error occured. */
/**
* 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);
/** Implement this function if the preset needs to be notified about
preset select and unselect events. */
/**
* 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);
};
/*
* fluid_sample_t
/**
* Virtual SoundFont sample.
*/
struct _fluid_sample_t
{
char name[21];
unsigned int start;
unsigned int end; /* Note: Index of last valid sample point (contrary to SF spec) */
unsigned int loopstart;
unsigned int loopend; /* Note: first point following the loop (superimposed on loopstart) */
unsigned int samplerate;
int origpitch;
int pitchadj;
int sampletype;
int valid;
short* data;
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 */
/** The amplitude, that will lower the level of the sample's loop to
the noise floor. Needed for note turnoff optimization, will be
filled out automatically */
/* Set this to zero, when submitting a new sample. */
int amplitude_that_reaches_noise_floor_is_valid;
double amplitude_that_reaches_noise_floor;
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. */
/** Count the number of playing voices that use this sample. */
unsigned int refcount;
unsigned int refcount; /**< Count of voices using this sample (use #fluid_sample_refcount to access this field) */
/** Implement this function if the sample or SoundFont needs to be
notified when the sample is no longer used. */
/**
* 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);
/** Pointer to SoundFont specific data */
void* userdata;
void* userdata; /**< User defined data */
};
#define fluid_sample_refcount(_sample) ((_sample)->refcount)
#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) */
/** Sample types */
#define FLUID_SAMPLETYPE_MONO 1
#define FLUID_SAMPLETYPE_RIGHT 2
#define FLUID_SAMPLETYPE_LEFT 4
#define FLUID_SAMPLETYPE_LINKED 8
#define FLUID_SAMPLETYPE_ROM 0x8000
#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 */

View file

@ -27,17 +27,13 @@ extern "C" {
#endif
/*
/**
* @file shell.h
* @brief Command shell interface
*
* Shell interface
*
* The shell interface allows you to send simple textual commands to
* the synthesizer, to parse a command file, or to read commands
* from the stdin or other input streams.
*
* To find the list of currently supported commands, please check the
* fluid_cmd.c file.
*
* The shell interface allows you to send simple textual commands to
* the synthesizer, to parse a command file, or to read commands
* from the stdin or other input streams.
*/
FLUIDSYNTH_API fluid_istream_t fluid_get_stdin(void);
@ -47,29 +43,22 @@ FLUIDSYNTH_API char* fluid_get_userconf(char* buf, int len);
FLUIDSYNTH_API char* fluid_get_sysconf(char* buf, int len);
/** The command structure */
typedef int (*fluid_cmd_func_t)(void* data, int ac, char** av, fluid_ostream_t out);
/**
* Shell command information structure.
*/
typedef struct {
char* name; /** The name of the command, as typed in in the shell */
char* topic; /** The help topic group of this command */
fluid_cmd_func_t handler; /** Pointer to the handler for this command */
void* data; /** Pointer to the user data */
char* help; /** A help string */
char* name; /**< The name of the command, as typed in the shell */
char* topic; /**< The help topic group of this command */
fluid_cmd_func_t handler; /**< Pointer to the handler for this command */
void* data; /**< User data passed to the handler */
char* help; /**< A help string */
} fluid_cmd_t;
/** The command handler */
/* The command handler */
/**
Create a new command handler. If the synth object passed as
argument is not NULL, the handler will add all the default
synthesizer commands to the command list.
\param synth The synthesizer object
\returns A new command handler
*/
FLUIDSYNTH_API
fluid_cmd_handler_t* new_fluid_cmd_handler(fluid_synth_t* synth);
@ -79,14 +68,6 @@ void delete_fluid_cmd_handler(fluid_cmd_handler_t* handler);
FLUIDSYNTH_API
void fluid_cmd_handler_set_synth(fluid_cmd_handler_t* handler, fluid_synth_t* synth);
/**
Register a new command to the handler. The handler makes a private
copy of the 'cmd' structure passed as argument.
\param handler A pointer to the command handler
\param cmd A pointer to the command structure
\returns 0 if the command was inserted, non-zero if error
*/
FLUIDSYNTH_API
int fluid_cmd_handler_register(fluid_cmd_handler_t* handler, fluid_cmd_t* cmd);
@ -94,7 +75,7 @@ FLUIDSYNTH_API
int fluid_cmd_handler_unregister(fluid_cmd_handler_t* handler, char* cmd);
/** Command function */
/* Command function */
FLUIDSYNTH_API
int fluid_command(fluid_cmd_handler_t* handler, char* cmd, fluid_ostream_t out);
@ -106,7 +87,7 @@ FLUIDSYNTH_API
void fluid_usershell(fluid_settings_t* settings, fluid_cmd_handler_t* handler);
/** Shell */
/* Shell */
FLUIDSYNTH_API
fluid_shell_t* new_fluid_shell(fluid_settings_t* settings, fluid_cmd_handler_t* handler,
@ -116,8 +97,14 @@ FLUIDSYNTH_API void delete_fluid_shell(fluid_shell_t* shell);
/** TCP/IP server */
/* TCP/IP server */
/**
* Callback function which is executed for new server connections.
* @param data User defined data supplied in call to new_fluid_server()
* @param addr The IP address of the client (can be NULL)
* @return Should return a new command handler for the connection (new_fluid_cmd_handler()).
*/
typedef fluid_cmd_handler_t* (*fluid_server_newclient_func_t)(void* data, char* addr);
FLUIDSYNTH_API

View file

@ -28,7 +28,8 @@ extern "C" {
/**
* Embedded synthesizer
* @file synth.h
* @brief Embeddable SoundFont synthesizer
*
* You create a new synthesizer with new_fluid_synth() and you destroy
* if with delete_fluid_synth(). Use the settings structure to specify
@ -109,11 +110,10 @@ FLUIDSYNTH_API double fluid_synth_get_reverb_damp(fluid_synth_t* synth);
FLUIDSYNTH_API double fluid_synth_get_reverb_level(fluid_synth_t* synth);
FLUIDSYNTH_API double fluid_synth_get_reverb_width(fluid_synth_t* synth);
/* Default settings for the reverb */
#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f
#define FLUID_REVERB_DEFAULT_DAMP 0.0f
#define FLUID_REVERB_DEFAULT_WIDTH 0.5f
#define FLUID_REVERB_DEFAULT_LEVEL 0.9f
#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f /**< Default reverb room size */
#define FLUID_REVERB_DEFAULT_DAMP 0.0f /**< Default reverb damping */
#define FLUID_REVERB_DEFAULT_WIDTH 0.5f /**< Default reverb width */
#define FLUID_REVERB_DEFAULT_LEVEL 0.9f /**< Default reverb level */
/* Chorus */
@ -135,12 +135,11 @@ FLUIDSYNTH_API double fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth);
FLUIDSYNTH_API double fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth);
FLUIDSYNTH_API int fluid_synth_get_chorus_type(fluid_synth_t* synth); /* see fluid_chorus_mod */
/* Default settings for the chorus. */
#define FLUID_CHORUS_DEFAULT_N 3
#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f
#define FLUID_CHORUS_DEFAULT_SPEED 0.3f
#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f
#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE
#define FLUID_CHORUS_DEFAULT_N 3 /**< Default chorus voice count */
#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f /**< Default chorus level */
#define FLUID_CHORUS_DEFAULT_SPEED 0.3f /**< Default chorus speed */
#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f /**< Default chorus depth */
#define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE /**< Default chorus waveform type */
/* Audio and MIDI channels */
@ -172,11 +171,8 @@ enum fluid_interp {
FLUID_INTERP_7THORDER = 7, /**< Seventh-order interpolation */
};
/** Default interpolation method from #fluid_interp. */
#define FLUID_INTERP_DEFAULT FLUID_INTERP_4THORDER
/** Highest interpolation method from #fluid_interp. */
#define FLUID_INTERP_HIGHEST FLUID_INTERP_7THORDER
#define FLUID_INTERP_DEFAULT FLUID_INTERP_4THORDER /**< Default interpolation method from #fluid_interp. */
#define FLUID_INTERP_HIGHEST FLUID_INTERP_7THORDER /**< Highest interpolation method from #fluid_interp. */
/* Generator interface */

View file

@ -28,36 +28,36 @@ extern "C" {
#endif
/*
/**
* @file types.h
* @brief Type declarations
*/
Forward declarations
typedef struct _fluid_hashtable_t fluid_settings_t; /**< Configuration settings instance */
typedef struct _fluid_synth_t fluid_synth_t; /**< Synthesizer instance */
typedef struct _fluid_voice_t fluid_voice_t; /**< Synthesis voice instance */
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
typedef struct _fluid_preset_t fluid_preset_t; /**< SoundFont preset */
typedef struct _fluid_sample_t fluid_sample_t; /**< SoundFont sample */
typedef struct _fluid_mod_t fluid_mod_t; /**< SoundFont modulator */
typedef struct _fluid_audio_driver_t fluid_audio_driver_t; /**< Audio driver instance */
typedef struct _fluid_file_renderer_t fluid_file_renderer_t; /**< Audio file renderer instance */
typedef struct _fluid_player_t fluid_player_t; /**< MIDI player instance */
typedef struct _fluid_midi_event_t fluid_midi_event_t; /**< MIDI event */
typedef struct _fluid_midi_driver_t fluid_midi_driver_t; /**< MIDI driver instance */
typedef struct _fluid_midi_router_t fluid_midi_router_t; /**< MIDI router instance */
typedef struct _fluid_midi_router_rule_t fluid_midi_router_rule_t; /**< MIDI router rule */
typedef struct _fluid_hashtable_t fluid_cmd_handler_t; /**< Command handler */
typedef struct _fluid_shell_t fluid_shell_t; /**< Command shell */
typedef struct _fluid_server_t fluid_server_t; /**< TCP/IP shell server instance */
typedef struct _fluid_event_t fluid_event_t; /**< Sequencer event */
typedef struct _fluid_sequencer_t fluid_sequencer_t; /**< Sequencer instance */
typedef struct _fluid_ramsfont_t fluid_ramsfont_t; /**< RAM SoundFont */
typedef struct _fluid_rampreset_t fluid_rampreset_t; /**< RAM SoundFont preset */
*/
typedef struct _fluid_hashtable_t fluid_settings_t;
typedef struct _fluid_synth_t fluid_synth_t;
typedef struct _fluid_voice_t fluid_voice_t;
typedef struct _fluid_sfloader_t fluid_sfloader_t;
typedef struct _fluid_sfont_t fluid_sfont_t;
typedef struct _fluid_preset_t fluid_preset_t;
typedef struct _fluid_sample_t fluid_sample_t;
typedef struct _fluid_mod_t fluid_mod_t;
typedef struct _fluid_audio_driver_t fluid_audio_driver_t;
typedef struct _fluid_file_renderer_t fluid_file_renderer_t;
typedef struct _fluid_player_t fluid_player_t;
typedef struct _fluid_midi_event_t fluid_midi_event_t;
typedef struct _fluid_midi_driver_t fluid_midi_driver_t;
typedef struct _fluid_midi_router_t fluid_midi_router_t;
typedef struct _fluid_midi_router_rule_t fluid_midi_router_rule_t;
typedef struct _fluid_hashtable_t fluid_cmd_handler_t;
typedef struct _fluid_shell_t fluid_shell_t;
typedef struct _fluid_server_t fluid_server_t;
typedef struct _fluid_event_t fluid_event_t;
typedef struct _fluid_sequencer_t fluid_sequencer_t;
typedef struct _fluid_ramsfont_t fluid_ramsfont_t;
typedef struct _fluid_rampreset_t fluid_rampreset_t;
typedef int fluid_istream_t;
typedef int fluid_ostream_t;
typedef int fluid_istream_t; /**< Input stream descriptor */
typedef int fluid_ostream_t; /**< Output stream descriptor */
#ifdef __cplusplus

View file

@ -26,14 +26,17 @@
extern "C" {
#endif
#define FLUIDSYNTH_VERSION @FLUIDSYNTH_VERSION@
#define FLUIDSYNTH_VERSION_MAJOR @FLUIDSYNTH_VERSION_MAJOR@
#define FLUIDSYNTH_VERSION_MINOR @FLUIDSYNTH_VERSION_MINOR@
#define FLUIDSYNTH_VERSION_MICRO @FLUIDSYNTH_VERSION_MICRO@
/**
* @file version.h
* @brief Library version functions and defines
*/
#define FLUIDSYNTH_VERSION @FLUIDSYNTH_VERSION@ /**< String constant of libfluidsynth version. */
#define FLUIDSYNTH_VERSION_MAJOR @FLUIDSYNTH_VERSION_MAJOR@ /**< libfluidsynth major version integer constant. */
#define FLUIDSYNTH_VERSION_MINOR @FLUIDSYNTH_VERSION_MINOR@ /**< libfluidsynth minor version integer constant. */
#define FLUIDSYNTH_VERSION_MICRO @FLUIDSYNTH_VERSION_MICRO@ /**< libfluidsynth micro version integer constant. */
FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro);
FLUIDSYNTH_API char* fluid_version_str(void);

View file

@ -25,69 +25,36 @@
extern "C" {
#endif
/**
* @file voice.h
* @brief Synthesis voice manipulation functions.
*
* The interface to the synthesizer's voices.
* Examples on using them can be found in fluid_defsfont.c.
* Most of these functions should only be called from within synthesis context,
* such as the SoundFont loader's noteon method.
*/
/*
* The interface to the synthesizer's voices
* Examples on using them can be found in fluid_defsfont.c
*/
/** Update all the synthesis parameters, which depend on generator gen.
This is only necessary after changing a generator of an already operating voice.
Most applications will not need this function.*/
FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t* voice, int gen);
/* for fluid_voice_add_mod */
enum fluid_voice_add_mod{
FLUID_VOICE_OVERWRITE,
FLUID_VOICE_ADD,
FLUID_VOICE_DEFAULT
/**
* Enum used with fluid_voice_add_mod() to specify how to handle duplicate modulators.
*/
enum fluid_voice_add_mod {
FLUID_VOICE_OVERWRITE, /**< Overwrite any existing matching modulator */
FLUID_VOICE_ADD, /**< Add (sum) modulator amounts */
FLUID_VOICE_DEFAULT /**< For default modulators only, no need to check for duplicates */
};
/* Add a modulator to a voice (SF2.1 only). */
FLUIDSYNTH_API void fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode);
/** Set the value of a generator */
FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t* voice, int gen, float val);
/** Get the value of a generator */
FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t* voice, int gen);
/** Modify the value of a generator by val */
FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t* voice, int gen, float val);
/** Return the unique ID of the noteon-event. A sound font loader
* may store the voice processes it has created for * real-time
* control during the operation of a voice (for example: parameter
* changes in sound font editor). The synth uses a pool of
* voices, which are 'recycled' and never deallocated.
*
* Before modifying an existing voice, check
* - that its state is still 'playing'
* - that the ID is still the same
* Otherwise the voice has finished playing.
*/
FLUIDSYNTH_API unsigned int fluid_voice_get_id(fluid_voice_t* voice);
FLUIDSYNTH_API int fluid_voice_is_playing(fluid_voice_t* voice);
/** If the peak volume during the loop is known, then the voice can
* be released earlier during the release phase. Otherwise, the
* voice will operate (inaudibly), until the envelope is at the
* nominal turnoff point. In many cases the loop volume is many dB
* below the maximum volume. For example, the loop volume for a
* typical acoustic piano is 20 dB below max. Taking that into
* account in the turn-off algorithm we can save 20 dB / 100 dB =>
* 1/5 of the total release time.
* So it's a good idea to call fluid_voice_optimize_sample
* on each sample once.
*/
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t* s);
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t* s);
#ifdef __cplusplus

View file

@ -368,6 +368,7 @@ new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
* Like new_fluid_audio_driver() but allows for custom audio processing before
* audio is sent to audio driver. It is the responsibility of the callback
* 'func' to render the audio into the buffers.
*
* NOTE: Not as efficient as new_fluid_audio_driver().
*/
fluid_audio_driver_t*

View file

@ -36,6 +36,19 @@
#define MAX_COMMAND_LEN 1024 /* max command length accepted by fluid_command() */
#define FLUID_WORKLINELENGTH 1024 /* LADSPA plugins use long command lines */
struct _fluid_shell_t {
fluid_settings_t* settings;
fluid_cmd_handler_t* handler;
fluid_thread_t* thread;
fluid_istream_t in;
fluid_ostream_t out;
};
static int fluid_shell_run(fluid_shell_t* shell);
static void fluid_shell_init(fluid_shell_t* shell,
fluid_settings_t* settings, fluid_cmd_handler_t* handler,
fluid_istream_t in, fluid_ostream_t out);
void fluid_shell_settings(fluid_settings_t* settings)
{
fluid_settings_register_str(settings, "shell.prompt", "", 0, NULL, NULL);
@ -157,8 +170,8 @@ fluid_cmd_t fluid_commands[] = {
/**
* Process a string command.
* NOTE: FluidSynth 1.0.8+ no longer modifies the 'cmd' string.
* @param handle FluidSynth command handler
* NOTE: FluidSynth 1.0.8 and above no longer modifies the 'cmd' string.
* @param handler FluidSynth command handler
* @param cmd Command string (NOTE: Gets modified by FluidSynth prior to 1.0.8)
* @param out Output stream to display command response to
* @return Integer value corresponding to: -1 on command error, 0 on success,
@ -196,20 +209,6 @@ fluid_command(fluid_cmd_handler_t* handler, char* cmd, fluid_ostream_t out)
return fluid_cmd_handler_handle(handler, num_tokens, &token[0], out);
}
struct _fluid_shell_t {
fluid_settings_t* settings;
fluid_cmd_handler_t* handler;
fluid_thread_t* thread;
fluid_istream_t in;
fluid_ostream_t out;
};
int fluid_shell_run(fluid_shell_t* shell);
void fluid_shell_init(fluid_shell_t* shell,
fluid_settings_t* settings, fluid_cmd_handler_t* handler,
fluid_istream_t in, fluid_ostream_t out);
/**
* Create a new FluidSynth command shell.
* @param settings Setting parameters to use with the shell
@ -246,12 +245,12 @@ new_fluid_shell(fluid_settings_t* settings, fluid_cmd_handler_t* handler,
}
return shell;
}
void fluid_shell_init(fluid_shell_t* shell,
fluid_settings_t* settings, fluid_cmd_handler_t* handler,
fluid_istream_t in, fluid_ostream_t out)
static void
fluid_shell_init(fluid_shell_t* shell,
fluid_settings_t* settings, fluid_cmd_handler_t* handler,
fluid_istream_t in, fluid_ostream_t out)
{
shell->settings = settings;
shell->handler = handler;
@ -259,7 +258,12 @@ void fluid_shell_init(fluid_shell_t* shell,
shell->out = out;
}
void delete_fluid_shell(fluid_shell_t* shell)
/**
* Delete a FluidSynth command shell.
* @param shell Command shell instance
*/
void
delete_fluid_shell(fluid_shell_t* shell)
{
if (shell->thread != NULL) {
delete_fluid_thread(shell->thread);
@ -268,8 +272,8 @@ void delete_fluid_shell(fluid_shell_t* shell)
FLUID_FREE(shell);
}
int fluid_shell_run(fluid_shell_t* shell)
static int
fluid_shell_run(fluid_shell_t* shell)
{
char workline[FLUID_WORKLINELENGTH];
char* prompt = NULL;
@ -321,7 +325,12 @@ int fluid_shell_run(fluid_shell_t* shell)
return errors;
}
/**
* A convenience function to create a shell interfacing to standard input/output
* console streams.
* @param settings Settings instance for the shell
* @param handler Command handler callback
*/
void
fluid_usershell(fluid_settings_t* settings, fluid_cmd_handler_t* handler)
{
@ -330,6 +339,12 @@ fluid_usershell(fluid_settings_t* settings, fluid_cmd_handler_t* handler)
fluid_shell_run(&shell);
}
/**
* Execute shell commands in a file.
* @param handler Command handler callback
* @param filename File name
* @return 0 on success, a value >1 on error
*/
int
fluid_source(fluid_cmd_handler_t* handler, char* filename)
{
@ -348,7 +363,12 @@ fluid_source(fluid_cmd_handler_t* handler, char* filename)
return fluid_shell_run(&shell);
}
/**
* Get the user specific FluidSynth command file name.
* @param buf Caller supplied string buffer to store file name to.
* @param len Length of \a buf
* @return Returns \a buf pointer or NULL if no user command file for this system type.
*/
char*
fluid_get_userconf(char* buf, int len)
{
@ -365,6 +385,12 @@ fluid_get_userconf(char* buf, int len)
#endif
}
/**
* Get the system FluidSynth command file name.
* @param buf Caller supplied string buffer to store file name to.
* @param len Length of \a buf
* @return Returns \a buf pointer or NULL if no system command file for this system type.
*/
char*
fluid_get_sysconf(char* buf, int len)
{
@ -1589,7 +1615,14 @@ fluid_cmd_handler_destroy_hash_value (void *value)
delete_fluid_cmd ((fluid_cmd_t *)value);
}
fluid_cmd_handler_t* new_fluid_cmd_handler(fluid_synth_t* synth)
/**
* Create a new command handler.
* @param synth If not NULL, all the default synthesizer commands will be
* added to the new handler.
* @return New command handler
*/
fluid_cmd_handler_t *
new_fluid_cmd_handler(fluid_synth_t* synth)
{
int i;
fluid_cmd_handler_t* handler;
@ -1619,24 +1652,44 @@ fluid_cmd_handler_t* new_fluid_cmd_handler(fluid_synth_t* synth)
return handler;
}
void delete_fluid_cmd_handler(fluid_cmd_handler_t* handler)
/**
* Delete a command handler.
* @param handler Command handler to delete
*/
void
delete_fluid_cmd_handler(fluid_cmd_handler_t* handler)
{
delete_fluid_hashtable (handler);
}
int fluid_cmd_handler_register(fluid_cmd_handler_t* handler, fluid_cmd_t* cmd)
/**
* Register a new command to the handler.
* @param handler Command handler instance
* @param cmd Command info (gets copied)
* @return #FLUID_OK if command was inserted, #FLUID_FAILED otherwise
*/
int
fluid_cmd_handler_register(fluid_cmd_handler_t* handler, fluid_cmd_t* cmd)
{
fluid_cmd_t* copy = fluid_cmd_copy(cmd);
fluid_hashtable_insert(handler, copy->name, copy);
return 0;
return FLUID_OK;
}
int fluid_cmd_handler_unregister(fluid_cmd_handler_t* handler, char* cmd)
/**
* Unregister a command from a command handler.
* @param handler Command handler instance
* @param cmd Name of the command
* @return TRUE if command was found and unregistered, FALSE otherwise
*/
int
fluid_cmd_handler_unregister(fluid_cmd_handler_t* handler, char* cmd)
{
return fluid_hashtable_remove(handler, cmd);
}
int fluid_cmd_handler_handle(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out)
int
fluid_cmd_handler_handle(fluid_cmd_handler_t* handler, int ac, char** av, fluid_ostream_t out)
{
fluid_cmd_t* cmd;
@ -1668,6 +1721,13 @@ static void fluid_server_handle_connection(fluid_server_t* server,
char* addr);
static void fluid_server_close(fluid_server_t* server);
/**
* Create a new TCP/IP command shell server.
* @param settings Settings instance to use for the shell
* @param newclient Callback function to call for each new client connection
* @param data User defined data to pass to \a newclient callback
* @return New shell server instance or NULL on error
*/
fluid_server_t*
new_fluid_server(fluid_settings_t* settings,
fluid_server_newclient_func_t newclient,
@ -1702,7 +1762,12 @@ new_fluid_server(fluid_settings_t* settings,
return server;
}
void delete_fluid_server(fluid_server_t* server)
/**
* Delete a TCP/IP shell server.
* @param server Shell server instance
*/
void
delete_fluid_server(fluid_server_t* server)
{
if (server == NULL) {
return;
@ -1776,6 +1841,11 @@ void fluid_server_remove_client(fluid_server_t* server, fluid_client_t* client)
fluid_mutex_unlock(server->mutex);
}
/**
* Join a shell server thread (wait until it quits).
* @param server Shell server instance
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int fluid_server_join(fluid_server_t* server)
{
return fluid_server_socket_join(server->socket);

View file

@ -38,6 +38,12 @@ BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
}
#endif
/**
* Set the handle to the instance of the application on the Windows platform.
* @param Application instance pointer
*
* The handle is needed to open DirectSound.
*/
void fluid_set_hinstance(void* hinstance)
{
if (fluid_hinstance == NULL) {
@ -46,6 +52,10 @@ void fluid_set_hinstance(void* hinstance)
}
}
/**
* Get the handle to the instance of the application on the Windows platform.
* @return Application instance pointer or NULL if not set
*/
void* fluid_get_hinstance(void)
{
return (void*) fluid_hinstance;

View file

@ -124,18 +124,18 @@ typedef struct
*/
typedef struct
{
char type; /**< #fluid_event_queue_elem */
char type; /**< fluid_event_queue_elem */
union
{
fluid_midi_event_t midi; /**< If type == #FLUID_EVENT_QUEUE_ELEM_MIDI */
fluid_event_gen_t gen; /**< If type == #FLUID_EVENT_QUEUE_ELEM_GEN */
fluid_event_preset_t preset; /**< If type == #FLUID_EVENT_QUEUE_ELEM_PRESET */
fluid_event_reverb_t reverb; /**< If type == #FLUID_EVENT_QUEUE_ELEM_REVERB */
fluid_event_chorus_t chorus; /**< If type == #FLUID_EVENT_QUEUE_ELEM_CHORUS */
fluid_event_set_tuning_t set_tuning; /**< If type == #FLUID_EVENT_QUEUE_ELEM_SET_TUNING */
fluid_event_repl_tuning_t repl_tuning; /**< If type == #FLUID_EVENT_QUEUE_ELEM_REPL_TUNING */
fluid_event_unref_tuning_t unref_tuning; /**< If type == #FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING */
fluid_midi_event_t midi; /**< If type == FLUID_EVENT_QUEUE_ELEM_MIDI */
fluid_event_gen_t gen; /**< If type == FLUID_EVENT_QUEUE_ELEM_GEN */
fluid_event_preset_t preset; /**< If type == FLUID_EVENT_QUEUE_ELEM_PRESET */
fluid_event_reverb_t reverb; /**< If type == FLUID_EVENT_QUEUE_ELEM_REVERB */
fluid_event_chorus_t chorus; /**< If type == FLUID_EVENT_QUEUE_ELEM_CHORUS */
fluid_event_set_tuning_t set_tuning; /**< If type == FLUID_EVENT_QUEUE_ELEM_SET_TUNING */
fluid_event_repl_tuning_t repl_tuning; /**< If type == FLUID_EVENT_QUEUE_ELEM_REPL_TUNING */
fluid_event_unref_tuning_t unref_tuning; /**< If type == FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING */
double dval; /**< A floating point payload value */
int ival; /**< An integer payload value */
void *pval; /**< A pointer payload value */

View file

@ -129,16 +129,20 @@ const char *endian_names[] = {
* Create a new file renderer and open the file.
* @param synth The synth that creates audio data.
* @return the new object, or NULL on failure
* @since: 1.1.0
* @since 1.1.0
*
* NOTE: Uses the following settings from the synth object:
* audio.file.name: Output filename
* audio.file.type: File type, "auto" tries to determine type from filename
* extension with fallback to "wav".
* audio.file.format: Audio format
* audio.file.endian: Endian byte order, "auto" for file type's default byte order
* audio.period-size: Size of audio blocks to process
* synth.sample-rate: Sample rate to use
* NOTE: Available file types and formats depends on if libfluidsynth was
* built with libsndfile support or not. If not then only RAW 16 bit output is
* supported.
*
* Uses the following settings from the synth object:
* - audio.file.name: Output filename
* - audio.file.type: File type, "auto" tries to determine type from filename
* extension with fallback to "wav".
* - audio.file.format: Audio format
* - audio.file.endian: Endian byte order, "auto" for file type's default byte order
* - audio.period-size: Size of audio blocks to process
* - synth.sample-rate: Sample rate to use
*/
fluid_file_renderer_t *
new_fluid_file_renderer(fluid_synth_t* synth)
@ -241,7 +245,7 @@ new_fluid_file_renderer(fluid_synth_t* synth)
/**
* Close file and destroy a file renderer object.
* @param dev File renderer object.
* @since: 1.1.0
* @since 1.1.0
*/
void delete_fluid_file_renderer(fluid_file_renderer_t* dev)
{
@ -274,7 +278,7 @@ void delete_fluid_file_renderer(fluid_file_renderer_t* dev)
* Write period_size samples to file.
* @param dev File renderer instance
* @return FLUID_OK or FLUID_FAILED if an error occurred
* @since: 1.1.0
* @since 1.1.0
*/
int
fluid_file_renderer_process_block(fluid_file_renderer_t* dev)

View file

@ -35,7 +35,7 @@ extern lash_client_t * fluid_lash_client;
#define fluid_lash_alsa_client_id lash_alsa_client_id
#define fluid_lash_jack_client_name lash_jack_client_name
#else /* old depricated LADCCA support which will be removed someday */
#else /* old deprecated LADCCA support which will be removed someday */
#include <ladcca/ladcca.h>
extern cca_client_t * fluid_lash_client;

View file

@ -198,11 +198,11 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
/**
* Write a list of midi driver names into a buffer.
* Write a list of MIDI driver names into a buffer.
* (A buffer length of 256 characters should be more than enough.)
* @param buf buffert to write names into
* @param buflen maximum amount of characters in buf.
* @param separator separator string, written between names.
* @param buf Buffer to write names into
* @param buflen Maximum amount of characters in buf.
* @param separator Separator string, written between names.
* @since 1.1.0
*/
void

View file

@ -676,7 +676,7 @@ fluid_midi_event_t* new_fluid_midi_event()
/**
* Delete MIDI event structure.
* @param evt MIDI event structure
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int delete_fluid_midi_event(fluid_midi_event_t* evt)
{
@ -686,7 +686,7 @@ int delete_fluid_midi_event(fluid_midi_event_t* evt)
{
temp = evt->next;
/* Dynamic SYSEX event? - free (param2 indicates if dynamic) */
/* Dynamic SYSEX event? - free (param2 indicates if dynamic) */
if (evt->type == MIDI_SYSEX && evt->paramptr && evt->param2)
FLUID_FREE (evt->paramptr);
@ -698,9 +698,8 @@ int delete_fluid_midi_event(fluid_midi_event_t* evt)
/**
* Get the event type field of a MIDI event structure.
* DOCME - Event type enum appears to be internal (fluid_midi.h)
* @param evt MIDI event structure
* @return Event type field
* @return Event type field (MIDI status byte without channel)
*/
int fluid_midi_event_get_type(fluid_midi_event_t* evt)
{
@ -709,10 +708,9 @@ int fluid_midi_event_get_type(fluid_midi_event_t* evt)
/**
* Set the event type field of a MIDI event structure.
* DOCME - Event type enum appears to be internal (fluid_midi.h)
* @param evt MIDI event structure
* @param type Event type field
* @return Always returns 0
* @param type Event type field (MIDI status byte without channel)
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_type(fluid_midi_event_t* evt, int type)
{
@ -734,7 +732,7 @@ int fluid_midi_event_get_channel(fluid_midi_event_t* evt)
* Set the channel field of a MIDI event structure.
* @param evt MIDI event structure
* @param chan MIDI channel field
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_channel(fluid_midi_event_t* evt, int chan)
{
@ -756,7 +754,7 @@ int fluid_midi_event_get_key(fluid_midi_event_t* evt)
* Set the key field of a MIDI event structure.
* @param evt MIDI event structure
* @param v MIDI note number (0-127)
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_key(fluid_midi_event_t* evt, int v)
{
@ -778,7 +776,7 @@ int fluid_midi_event_get_velocity(fluid_midi_event_t* evt)
* Set the velocity field of a MIDI event structure.
* @param evt MIDI event structure
* @param v MIDI velocity value
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_velocity(fluid_midi_event_t* evt, int v)
{
@ -800,7 +798,7 @@ int fluid_midi_event_get_control(fluid_midi_event_t* evt)
* Set the control field of a MIDI event structure.
* @param evt MIDI event structure
* @param v MIDI control number
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_control(fluid_midi_event_t* evt, int v)
{
@ -822,7 +820,7 @@ int fluid_midi_event_get_value(fluid_midi_event_t* evt)
* Set the value field of a MIDI event structure.
* @param evt MIDI event structure
* @param v Value to assign
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_value(fluid_midi_event_t* evt, int v)
{
@ -844,7 +842,7 @@ int fluid_midi_event_get_program(fluid_midi_event_t* evt)
* Set the program field of a MIDI event structure.
* @param evt MIDI event structure
* @param val MIDI program number (0-127)
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val)
{
@ -855,7 +853,7 @@ int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val)
/**
* Get the pitch field of a MIDI event structure.
* @param evt MIDI event structure
* @return Pitch value (DOCME units?)
* @return Pitch value (14 bit value, 0-16383, 8192 is center)
*/
int fluid_midi_event_get_pitch(fluid_midi_event_t* evt)
{
@ -865,7 +863,7 @@ int fluid_midi_event_get_pitch(fluid_midi_event_t* evt)
/**
* Set the pitch field of a MIDI event structure.
* @param evt MIDI event structure
* @param val Pitch value (DOCME units?)
* @param val Pitch value (14 bit value, 0-16383, 8192 is center)
* @return Always returns FLUID_OK
*/
int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val)
@ -882,7 +880,7 @@ int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val)
* @param dynamic TRUE if the SYSEX data has been dynamically allocated and
* should be freed when the event is freed (only applies if event gets destroyed
* with delete_fluid_midi_event())
* @return Always returns FLUID_OK
* @return Always returns #FLUID_OK
*
* NOTE: Unlike the other event assignment functions, this one sets evt->type.
*/
@ -1134,7 +1132,7 @@ fluid_player_t* new_fluid_player(fluid_synth_t* synth)
/**
* Delete a MIDI player instance.
* @param player MIDI player instance
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int delete_fluid_player(fluid_player_t* player)
{
@ -1363,7 +1361,7 @@ int fluid_player_callback(void* data, unsigned int msec)
/**
* Activates play mode for a MIDI player if not already playing.
* @param player MIDI player instance
* @return 0 on success, -1 on failure
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int fluid_player_play(fluid_player_t* player)
{
@ -1397,7 +1395,7 @@ int fluid_player_play(fluid_player_t* player)
/**
* Stops a MIDI player.
* @param player MIDI player instance
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_player_stop(fluid_player_t* player)
{
@ -1422,9 +1420,10 @@ int fluid_player_get_status(fluid_player_t* player)
/**
* Enable looping of a MIDI player
* @param player MIDI player instance
* @param loop times left to loop the playlist. -1 means loop infinitely.
* @return Always returns 0
* @param loop Times left to loop the playlist. -1 means loop infinitely.
* @return Always returns #FLUID_OK
* @since 1.1.0
*
* For example, if you want to loop the playlist twice, set loop to 2
* and call this function before you start the player.
*/
@ -1438,8 +1437,7 @@ int fluid_player_set_loop(fluid_player_t* player, int loop)
* Set the tempo of a MIDI player.
* @param player MIDI player instance
* @param tempo Tempo to set playback speed to (DOCME - Units?)
* @return Always returns 0
*
* @return Always returns #FLUID_OK
*/
int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo)
{
@ -1458,7 +1456,7 @@ int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo)
* Set the tempo of a MIDI player in beats per minute.
* @param player MIDI player instance
* @param bpm Tempo in beats per minute
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int fluid_player_set_bpm(fluid_player_t* player, int bpm)
{
@ -1468,8 +1466,7 @@ int fluid_player_set_bpm(fluid_player_t* player, int bpm)
/**
* Wait for a MIDI player to terminate (when done playing).
* @param player MIDI player instance
* @return 0 on success, -1 otherwise
*
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int fluid_player_join(fluid_player_t* player)
{
@ -1480,8 +1477,6 @@ int fluid_player_join(fluid_player_t* player)
while (player->status == FLUID_PLAYER_PLAYING) {
#if defined(WIN32)
Sleep(10);
#elif defined(MACOS9)
/* FIXME: How do we sleep in Macos9? */
#else
usleep(10000);
#endif

View file

@ -32,8 +32,8 @@
* @param event_handler_data Caller defined data pointer which gets passed to 'handler'
* @return New MIDI router instance or NULL on error
*
* A midi handler connects to a midi input
* device and forwards incoming midi events to the synthesizer.
* The MIDI handler connects to a midi input device and forwards incoming MIDI
* events to the synthesizer, after being filtered/modified by the MIDI router.
*/
fluid_midi_router_t*
new_fluid_midi_router(fluid_settings_t* settings, handle_midi_event_func_t handler, void* event_handler_data)
@ -77,7 +77,7 @@ new_fluid_midi_router(fluid_settings_t* settings, handle_midi_event_func_t handl
/**
* Delete a MIDI router instance.
* @param router MIDI router to delete
* @return Always returns 0
* @return Always returns #FLUID_OK
*/
int
delete_fluid_midi_router(fluid_midi_router_t* router)
@ -249,9 +249,11 @@ int fluid_midi_router_end(fluid_midi_router_t* router){
/**
* Handle a MIDI event through a MIDI router instance.
* @param data MIDI router instance #fluid_midi_router_t (DOCME why is it a void *?)
* @param data MIDI router instance #fluid_midi_router_t, its a void * so that
* this function can be used as a callback for other subsystems
* (new_fluid_midi_driver() for example).
* @param event MIDI event to handle
* @return 0 on success, -1 otherwise
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* Purpose: The midi router is called for each event, that is received
* via the 'physical' midi input. Each event can trigger an arbitrary number
@ -260,7 +262,7 @@ int fluid_midi_router_end(fluid_midi_router_t* router){
* In default mode, a noteon event is just forwarded to the synth's 'noteon' function,
* a 'CC' event to the synth's 'CC' function and so on.
*
* The router can be used to
* The router can be used to:
* - filter messages (for example: Pass sustain pedal CCs only to selected channels),
* - split the keyboard (noteon with notenr < x: to ch 1, >x to ch 2),
* - layer sounds (for each noteon received on ch 1, create a noteon on ch1, ch2, ch3,...)
@ -817,7 +819,7 @@ void fluid_midi_router_free_unused_rules(fluid_midi_router_t* router)
* MIDI event callback function to display event information to stdout
* @param data MIDI router instance
* @param event MIDI event data
* @return 0 on success, -1 otherwise
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* An implementation of the #handle_midi_event_func_t function type, used for
* displaying MIDI event information between the MIDI driver and router to
@ -861,7 +863,7 @@ int fluid_midi_dump_prerouter(void* data, fluid_midi_event_t* event)
* MIDI event callback function to display event information to stdout
* @param data MIDI router instance
* @param event MIDI event data
* @return 0 on success, -1 otherwise
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* An implementation of the #handle_midi_event_func_t function type, used for
* displaying MIDI event information between the MIDI driver and router to

View file

@ -26,23 +26,72 @@
#define SAMPLE_LOOP_MARGIN 8
/* Prototypes */
int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample, int lokey, int hikey);
int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sample, int gen_type, float value);
int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sample, int on, float loopstart, float loopend);
int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample);
void fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val);
static int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont);
static char *fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont);
static fluid_preset_t *fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont,
unsigned int bank,
unsigned int prenum);
static void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont);
static int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont,
fluid_preset_t* preset);
static int fluid_rampreset_preset_delete(fluid_preset_t* preset);
static char *fluid_rampreset_preset_get_name(fluid_preset_t* preset);
static int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset);
static int fluid_rampreset_preset_get_num(fluid_preset_t* preset);
static int fluid_rampreset_preset_noteon(fluid_preset_t* preset,
fluid_synth_t* synth, int chan,
int key, int vel);
static fluid_ramsfont_t *new_fluid_ramsfont (void);
static int delete_fluid_ramsfont (fluid_ramsfont_t* sfont);
static char *fluid_ramsfont_get_name(fluid_ramsfont_t* sfont);
static int fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont,
fluid_rampreset_t* preset);
static fluid_rampreset_t *fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num);
static void fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont);
static int fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont,
fluid_preset_t* preset);
static fluid_rampreset_t* new_fluid_rampreset(fluid_ramsfont_t* sfont);
static int delete_fluid_rampreset (fluid_rampreset_t* preset);
static int fluid_rampreset_get_banknum (fluid_rampreset_t* preset);
static int fluid_rampreset_get_num (fluid_rampreset_t* preset);
static char *fluid_rampreset_get_name (fluid_rampreset_t* preset);
static fluid_rampreset_t *fluid_rampreset_next (fluid_rampreset_t* preset);
static int fluid_rampreset_add_zone(fluid_rampreset_t* preset,
fluid_preset_zone_t* zone);
static int fluid_rampreset_add_sample (fluid_rampreset_t* preset,
fluid_sample_t* sample,
int lokey, int hikey);
static fluid_inst_zone_t *fluid_rampreset_izoneforsample (fluid_rampreset_t* preset,
fluid_sample_t* sample);
static int fluid_rampreset_izone_set_loop (fluid_rampreset_t* preset,
fluid_sample_t* sample,
int on, float loopstart, float loopend);
static int fluid_rampreset_izone_set_gen (fluid_rampreset_t* preset,
fluid_sample_t* sample,
int gen_type, float value);
static int fluid_rampreset_remove_izone(fluid_rampreset_t* preset,
fluid_sample_t* sample);
static int fluid_rampreset_remembervoice (fluid_rampreset_t* preset,
fluid_voice_t* voice);
static void fluid_rampreset_updatevoices (fluid_rampreset_t* preset,
int gen_type, float val);
static int fluid_rampreset_noteon (fluid_rampreset_t* preset, fluid_synth_t* synth,
int chan, int key, int vel);
/*
* fluid_ramsfont_create_sfont
/**
* Create a #fluid_sfont_t wrapping a #fluid_ramsfont_t
* @return New #fluid_sfont_t or NULL if out of memory
*/
fluid_sfont_t*
fluid_ramsfont_create_sfont()
{
fluid_sfont_t* sfont;
fluid_ramsfont_t* ramsfont;
fluid_sfont_t* sfont;
fluid_ramsfont_t* ramsfont;
ramsfont = new_fluid_ramsfont();
if (ramsfont == NULL) {
ramsfont = new_fluid_ramsfont();
if (ramsfont == NULL) {
return NULL;
}
@ -60,28 +109,28 @@ fluid_ramsfont_create_sfont()
sfont->iteration_next = fluid_ramsfont_sfont_iteration_next;
return sfont;
}
/***************************************************************
*
* PUBLIC INTERFACE
*/
int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont)
/* RAM SoundFont loader method to delete SoundFont */
static int
fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont)
{
if (delete_fluid_ramsfont(sfont->data) != 0)
return -1;
FLUID_FREE(sfont);
return 0;
if (delete_fluid_ramsfont(sfont->data) != 0)
return -1;
FLUID_FREE(sfont);
return 0;
}
char* fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont)
/* RAM SoundFont loader method to get name */
static char *
fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont)
{
return fluid_ramsfont_get_name((fluid_ramsfont_t*) sfont->data);
}
fluid_preset_t* fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
/* RAM SoundFont loader method to get a preset */
static fluid_preset_t *
fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
{
fluid_preset_t* preset;
fluid_rampreset_t* rampreset;
@ -110,12 +159,16 @@ fluid_preset_t* fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned i
return preset;
}
void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont)
/* RAM SoundFont loader method to start preset iteration */
static void
fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont)
{
fluid_ramsfont_iteration_start((fluid_ramsfont_t*) sfont->data);
}
int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
/* RAM SoundFont loader method to advance preset iteration */
static int
fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
{
preset->free = fluid_rampreset_preset_delete;
preset->get_name = fluid_rampreset_preset_get_name;
@ -127,7 +180,9 @@ int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* pr
return fluid_ramsfont_iteration_next((fluid_ramsfont_t*) sfont->data, preset);
}
int fluid_rampreset_preset_delete(fluid_preset_t* preset)
/* RAM SoundFont loader delete preset method */
static int
fluid_rampreset_preset_delete(fluid_preset_t* preset)
{
FLUID_FREE(preset);
@ -136,22 +191,30 @@ int fluid_rampreset_preset_delete(fluid_preset_t* preset)
return 0;
}
char* fluid_rampreset_preset_get_name(fluid_preset_t* preset)
/* RAM SoundFont loader get preset name method */
static char *
fluid_rampreset_preset_get_name(fluid_preset_t* preset)
{
return fluid_rampreset_get_name((fluid_rampreset_t*) preset->data);
}
int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset)
/* RAM SoundFont loader get preset bank method */
static int
fluid_rampreset_preset_get_banknum(fluid_preset_t* preset)
{
return fluid_rampreset_get_banknum((fluid_rampreset_t*) preset->data);
}
int fluid_rampreset_preset_get_num(fluid_preset_t* preset)
/* RAM SoundFont loader get preset program method */
static int
fluid_rampreset_preset_get_num(fluid_preset_t* preset)
{
return fluid_rampreset_get_num((fluid_rampreset_t*) preset->data);
}
int fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
/* RAM SoundFont loader preset noteon method */
static int
fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
{
return fluid_rampreset_noteon((fluid_rampreset_t*) preset->data, synth, chan, key, vel);
}
@ -164,10 +227,8 @@ int fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth,
* SFONT
*/
/*
* new_fluid_ramsfont
*/
fluid_ramsfont_t* new_fluid_ramsfont()
static fluid_ramsfont_t *
new_fluid_ramsfont (void)
{
fluid_ramsfont_t* sfont;
@ -184,10 +245,8 @@ fluid_ramsfont_t* new_fluid_ramsfont()
return sfont;
}
/*
* delete_fluid_ramsfont
*/
int delete_fluid_ramsfont(fluid_ramsfont_t* sfont)
static int
delete_fluid_ramsfont (fluid_ramsfont_t* sfont)
{
fluid_list_t *list;
fluid_rampreset_t* preset;
@ -221,30 +280,29 @@ int delete_fluid_ramsfont(fluid_ramsfont_t* sfont)
return FLUID_OK;
}
/*
* fluid_ramsfont_get_name
*/
char* fluid_ramsfont_get_name(fluid_ramsfont_t* sfont)
static char *
fluid_ramsfont_get_name(fluid_ramsfont_t* sfont)
{
return sfont->name;
}
/*
* fluid_ramsfont_set_name
/**
* Set a RAM SoundFont name.
* @param sfont RAM SoundFont
* @param name Name to assign (should be 20 chars in length with a NULL terminator)
* @return #FLUID_OK
*/
int
fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, char * name)
fluid_ramsfont_set_name (fluid_ramsfont_t *sfont, char *name)
{
FLUID_MEMCPY(sfont->name, name, 20);
return FLUID_OK;
}
/* fluid_ramsfont_add_preset
*
* Add a preset to the SoundFont
*/
int fluid_ramsfont_add_preset(fluid_ramsfont_t* sfont, fluid_rampreset_t* preset)
/* Add a preset to a RAM SoundFont */
static int
fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont, fluid_rampreset_t* preset)
{
fluid_rampreset_t *cur, *prev;
if (sfont->preset == NULL) {
@ -275,12 +333,21 @@ int fluid_ramsfont_add_preset(fluid_ramsfont_t* sfont, fluid_rampreset_t* preset
return FLUID_OK;
}
/*
* fluid_ramsfont_add_ramsample
/**
* Creates one instrument zone for the sample inside the preset defined by
* \a bank and \a num
* @param sfont RAM SoundFont
* @param bank Preset bank number
* @param num Preset program number
* @param sample Sample to use for instrument zone
* @param lokey Lower MIDI key range of zone (0-127, <= \a hikey)
* @param hikey Upper MIDI key range of zone (0-127, >= \a lokey)
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int lokey, int hikey)
int
fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample,
int lokey, int hikey)
{
/*- find or create a preset
- add it the sample using the fluid_rampreset_add_sample fucntion
@ -320,8 +387,18 @@ int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont,
return FLUID_OK;
}
int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample) {
/**
* Removes the instrument zone corresponding to \a bank, \a num and \a sample
* @param sfont RAM SoundFont
* @param bank Preset bank number
* @param num Preset program number
* @param sample Sample of the preset zone
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int
fluid_ramsfont_remove_izone (fluid_ramsfont_t* sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample)
{
int err;
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
@ -340,12 +417,21 @@ int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont,
return FLUID_OK;
}
/* Note for version 2.0 : missing API fluid_ramsfont_izone_get_gen - Antoine Schmitt May 2003 */
int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int gen_type, float value) {
/**
* Sets a generator on an instrument zone identified by \a bank, \a num and \a sample
* @param sfont RAM SoundFont
* @param bank Preset bank number
* @param num Preset program number
* @param sample Sample of the instrument zone.
* @param gen_type Generator ID (#fluid_gen_type)
* @param value Generator value
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int
fluid_ramsfont_izone_set_gen (fluid_ramsfont_t* sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample,
int gen_type, float value)
{
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
@ -354,10 +440,24 @@ int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont,
return fluid_rampreset_izone_set_gen(preset, sample, gen_type, value);
}
/* Note for version 2.0 : missing API fluid_ramsfont_izone_get_loop - Antoine Schmitt May 2003 */
int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont,
unsigned int bank, unsigned int num, fluid_sample_t* sample,
int on, float loopstart, float loopend) {
/**
* Sets loop start/end values of the instrument zone identified by \a bank,
* \a num and \a sample.
* @param sfont RAM SoundFont
* @param bank Preset bank number
* @param num Preset program number
* @param sample Sample of the instrument zone
* @param on TRUE to enable looping, FALSE for one shot (\a loopstart and \a loopend
* not used)
* @param loopstart Loop start, in frames (counted from 0)
* @param loopend Loop end, in frames (counted from last frame, thus is < 0)
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int
fluid_ramsfont_izone_set_loop (fluid_ramsfont_t *sfont, unsigned int bank,
unsigned int num, fluid_sample_t* sample,
int on, float loopstart, float loopend)
{
fluid_rampreset_t* preset = fluid_ramsfont_get_preset(sfont, bank, num);
if (preset == NULL) {
return FLUID_FAILED;
@ -366,10 +466,9 @@ int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont,
return fluid_rampreset_izone_set_loop(preset, sample, on, loopstart, loopend);
}
/*
* fluid_ramsfont_get_preset
*/
fluid_rampreset_t* fluid_ramsfont_get_preset(fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num)
/* Get a preset from a RAM SoundFont */
static fluid_rampreset_t *
fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num)
{
fluid_rampreset_t* preset = sfont->preset;
while (preset != NULL) {
@ -381,18 +480,16 @@ fluid_rampreset_t* fluid_ramsfont_get_preset(fluid_ramsfont_t* sfont, unsigned i
return NULL;
}
/*
* fluid_ramsfont_iteration_start
*/
void fluid_ramsfont_iteration_start(fluid_ramsfont_t* sfont)
/* Start preset iteration in a RAM SoundFont */
static void
fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont)
{
sfont->iter_cur = sfont->preset;
}
/*
* fluid_ramsfont_iteration_next
*/
int fluid_ramsfont_iteration_next(fluid_ramsfont_t* sfont, fluid_preset_t* preset)
/* Advance preset iteration in a RAM SoundFont */
static int
fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont, fluid_preset_t* preset)
{
if (sfont->iter_cur == NULL) {
return 0;
@ -414,10 +511,8 @@ struct _fluid_rampreset_voice_t {
unsigned int voiceID;
};
/*
* new_fluid_rampreset
*/
fluid_rampreset_t*
/* Create a new RAM SoundFont preset */
static fluid_rampreset_t*
new_fluid_rampreset(fluid_ramsfont_t* sfont)
{
fluid_rampreset_t* preset = FLUID_NEW(fluid_rampreset_t);
@ -436,11 +531,9 @@ new_fluid_rampreset(fluid_ramsfont_t* sfont)
return preset;
}
/*
* delete_fluid_rampreset
*/
int
delete_fluid_rampreset(fluid_rampreset_t* preset)
/* Delete a RAM SoundFont preset */
static int
delete_fluid_rampreset (fluid_rampreset_t* preset)
{
int err = FLUID_OK;
fluid_preset_zone_t* zone;
@ -478,38 +571,37 @@ delete_fluid_rampreset(fluid_rampreset_t* preset)
return err;
}
int
fluid_rampreset_get_banknum(fluid_rampreset_t* preset)
/* Get a RAM SoundFont preset bank */
static int
fluid_rampreset_get_banknum (fluid_rampreset_t* preset)
{
return preset->bank;
}
int
fluid_rampreset_get_num(fluid_rampreset_t* preset)
/* Get a RAM SoundFont preset program */
static int
fluid_rampreset_get_num (fluid_rampreset_t* preset)
{
return preset->num;
}
char*
fluid_rampreset_get_name(fluid_rampreset_t* preset)
/* Get a RAM SoundFont preset name */
static char *
fluid_rampreset_get_name (fluid_rampreset_t* preset)
{
return preset->name;
}
/*
* fluid_rampreset_next
*/
fluid_rampreset_t*
fluid_rampreset_next(fluid_rampreset_t* preset)
/* Advance to next preset */
static fluid_rampreset_t *
fluid_rampreset_next (fluid_rampreset_t* preset)
{
return preset->next;
}
/*
* fluid_rampreset_add_zone
*/
int
/* Add a zone to a RAM SoundFont preset */
static int
fluid_rampreset_add_zone(fluid_rampreset_t* preset, fluid_preset_zone_t* zone)
{
if (preset->zone == NULL) {
@ -522,11 +614,10 @@ fluid_rampreset_add_zone(fluid_rampreset_t* preset, fluid_preset_zone_t* zone)
return FLUID_OK;
}
/*
* fluid_rampreset_add_sample
*/
int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample, int lokey, int hikey)
/* Add a sample to a RAM SoundFont preset */
static int
fluid_rampreset_add_sample (fluid_rampreset_t* preset, fluid_sample_t* sample,
int lokey, int hikey)
{
/* create a new instrument zone, with the given sample */
@ -572,7 +663,9 @@ int fluid_rampreset_add_sample(fluid_rampreset_t* preset, fluid_sample_t* sample
return FLUID_OK;
}
fluid_inst_zone_t* fluid_rampreset_izoneforsample(fluid_rampreset_t* preset, fluid_sample_t* sample)
/* Find an instrument zone with the given sample */
static fluid_inst_zone_t *
fluid_rampreset_izoneforsample (fluid_rampreset_t* preset, fluid_sample_t* sample)
{
fluid_inst_t* inst;
fluid_inst_zone_t* izone;
@ -589,8 +682,11 @@ fluid_inst_zone_t* fluid_rampreset_izoneforsample(fluid_rampreset_t* preset, flu
return NULL;
}
int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sample,
int on, float loopstart, float loopend) {
/* Set loop of an instrument zone */
static int
fluid_rampreset_izone_set_loop (fluid_rampreset_t* preset, fluid_sample_t* sample,
int on, float loopstart, float loopend)
{
fluid_inst_zone_t* izone = fluid_rampreset_izoneforsample(preset, sample);
short coarse, fine;
@ -602,7 +698,7 @@ int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sa
izone->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
fluid_rampreset_updatevoices(preset, GEN_SAMPLEMODE, FLUID_UNLOOPED);
return FLUID_OK;
}
}
/* NOTE : We should check that (sample->startloop + loopStart <= sample->endloop - loopend - 32) */
@ -656,8 +752,11 @@ int fluid_rampreset_izone_set_loop(fluid_rampreset_t* preset, fluid_sample_t* sa
return FLUID_OK;
}
int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sample,
int gen_type, float value) {
/* Set a generator on the instrument zone in preset having sample */
static int
fluid_rampreset_izone_set_gen (fluid_rampreset_t* preset, fluid_sample_t* sample,
int gen_type, float value)
{
fluid_inst_zone_t* izone = fluid_rampreset_izoneforsample(preset, sample);
if (izone == NULL)
return FLUID_FAILED;
@ -670,7 +769,10 @@ int fluid_rampreset_izone_set_gen(fluid_rampreset_t* preset, fluid_sample_t* sam
return FLUID_OK;
}
int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample) {
/* Remove the instrument zone from preset having sample */
static int
fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* sample)
{
fluid_inst_t* inst;
fluid_inst_zone_t* izone, * prev;
int found = 0;
@ -718,14 +820,12 @@ int fluid_rampreset_remove_izone(fluid_rampreset_t* preset, fluid_sample_t* samp
return FLUID_OK;
}
/*
* fluid_rampreset_remembervoice
*/
int
fluid_rampreset_remembervoice(fluid_rampreset_t* preset, fluid_voice_t* voice) {
/* stores the voice and the its ID in the preset for later update on gen_set */
fluid_rampreset_voice_t *presetvoice = FLUID_NEW(fluid_rampreset_voice_t);
if (presetvoice == NULL) {
/* Stores the voice and the its ID in the preset for later update on gen_set */
static int
fluid_rampreset_remembervoice (fluid_rampreset_t* preset, fluid_voice_t* voice)
{
fluid_rampreset_voice_t *presetvoice = FLUID_NEW(fluid_rampreset_voice_t);
if (presetvoice == NULL) {
FLUID_LOG(FLUID_ERR, "Out of memory");
return FLUID_FAILED;
}
@ -742,16 +842,15 @@ fluid_rampreset_remembervoice(fluid_rampreset_t* preset, fluid_voice_t* voice) {
return FLUID_OK;
}
/*
* fluid_rampreset_updatevoice
*/
void
fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val) {
/* Update a generator in realtime for a preset */
static void
fluid_rampreset_updatevoices (fluid_rampreset_t* preset, int gen_type, float val)
{
fluid_list_t *tmp = preset->presetvoices, *prev = NULL, *next;
/* walk the presetvoice to update them if they are still active and ours.
If their ID has changed or their state is not playing, they are not ours, so we forget them
*/
/* Walk the presetvoice to update them if they are still active and ours.
* If their ID has changed or their state is not playing, they are not
* ours, so we forget them. */
while (tmp) {
fluid_rampreset_voice_t *presetvoice = (fluid_rampreset_voice_t *)(tmp->data);
fluid_voice_t *voice = presetvoice->voice;
@ -783,11 +882,10 @@ fluid_rampreset_updatevoices(fluid_rampreset_t* preset, int gen_type, float val)
}
/*
* fluid_rampreset_noteon
*/
int
fluid_rampreset_noteon(fluid_rampreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
/* RAM SoundFont preset note on */
static int
fluid_rampreset_noteon (fluid_rampreset_t* preset, fluid_synth_t* synth, int chan,
int key, int vel)
{
fluid_preset_zone_t *preset_zone;
fluid_inst_t* inst;
@ -1011,22 +1109,34 @@ fluid_rampreset_noteon(fluid_rampreset_t* preset, fluid_synth_t* synth, int chan
*/
/*
* fluid_sample_set_name
/**
* Set the name of a RAM SoundFont sample.
* @param sample RAM SoundFont sample
* @param name Name to assign to sample (20 chars in length, 0 terminated)
* @return #FLUID_OK
*/
int
fluid_sample_set_name(fluid_sample_t* sample, char * name)
fluid_sample_set_name(fluid_sample_t* sample, char* name)
{
FLUID_MEMCPY(sample->name, name, 20);
return FLUID_OK;
}
/*
* fluid_sample_set_sound_data
/**
* Assign sample data to a RAM SoundFont sample.
* @param sample RAM SoundFont sample
* @param data Buffer containing 16 bit audio sample data
* @param nbframes Number of samples in \a data
* @param copy_data TRUE to copy the data, FALSE to use it directly
* @param rootkey Root MIDI note of sample (0-127)
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* WARNING: If \a copy_data is FALSE, data should have 8 unused frames at start
* and 8 unused frames at the end.
*/
int
fluid_sample_set_sound_data(fluid_sample_t* sample, short *data, unsigned int nbframes, short copy_data, int rootkey)
fluid_sample_set_sound_data (fluid_sample_t* sample, short *data,
unsigned int nbframes, short copy_data, int rootkey)
{
/* 16 bit mono 44.1KHz data in */
/* in all cases, the sample has ownership of the data : it will release it in the end */
@ -1081,11 +1191,12 @@ fluid_sample_set_sound_data(fluid_sample_t* sample, short *data, unsigned int nb
return FLUID_OK;
}
/*
* new_fluid_ramsample
/**
* Create new RAM SoundFont sample.
* @return New RAM SoundFont sample or NULL if out of memory
*/
fluid_sample_t*
new_fluid_ramsample()
fluid_sample_t *
new_fluid_ramsample (void)
{
/* same as new_fluid_sample. Only here so that it is exported */
fluid_sample_t* sample = NULL;
@ -1101,11 +1212,13 @@ new_fluid_ramsample()
return sample;
}
/*
* delete_fluid_ramsample
/**
* Delete a RAM SoundFont sample.
* @param sample Sample to delete
* @return #FLUID_OK
*/
int
delete_fluid_ramsample(fluid_sample_t* sample)
delete_fluid_ramsample (fluid_sample_t* sample)
{
/* same as delete_fluid_sample, plus frees the data */
if (sample->data != NULL) {

View file

@ -34,28 +34,7 @@ extern "C" {
#endif
/*
Public interface
*/
int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont);
char* fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont);
fluid_preset_t* fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum);
void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont);
int fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset);
int fluid_rampreset_preset_delete(fluid_preset_t* preset);
char* fluid_rampreset_preset_get_name(fluid_preset_t* preset);
int fluid_rampreset_preset_get_banknum(fluid_preset_t* preset);
int fluid_rampreset_preset_get_num(fluid_preset_t* preset);
int fluid_rampreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel);
/*
/*
* fluid_ramsfont_t
*/
struct _fluid_ramsfont_t
@ -68,17 +47,6 @@ struct _fluid_ramsfont_t
fluid_rampreset_t* iter_cur; /* the current preset in the iteration */
};
/* interface */
fluid_ramsfont_t* new_fluid_ramsfont(void);
int delete_fluid_ramsfont(fluid_ramsfont_t* sfont);
char* fluid_ramsfont_get_name(fluid_ramsfont_t* sfont);
fluid_rampreset_t* fluid_ramsfont_get_preset(fluid_ramsfont_t* sfont, unsigned int bank, unsigned int prenum);
void fluid_ramsfont_iteration_start(fluid_ramsfont_t* sfont);
int fluid_ramsfont_iteration_next(fluid_ramsfont_t* sfont, fluid_preset_t* preset);
/* specific */
/*
* fluid_preset_t
*/
@ -94,18 +62,6 @@ struct _fluid_rampreset_t
fluid_list_t *presetvoices; /* chained list of used voices */
};
/* interface */
fluid_rampreset_t* new_fluid_rampreset(fluid_ramsfont_t* sfont);
int delete_fluid_rampreset(fluid_rampreset_t* preset);
fluid_rampreset_t* fluid_rampreset_next(fluid_rampreset_t* preset);
char* fluid_rampreset_get_name(fluid_rampreset_t* preset);
int fluid_rampreset_get_banknum(fluid_rampreset_t* preset);
int fluid_rampreset_get_num(fluid_rampreset_t* preset);
int fluid_rampreset_noteon(fluid_rampreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel);
#ifdef __cplusplus
}

View file

@ -74,36 +74,41 @@ typedef struct _fluid_sequencer_client_t {
} fluid_sequencer_client_t;
/* prototypes */
/* sorting API */
short _fluid_seq_queue_init(fluid_sequencer_t* seq, int nbEvents);
void _fluid_seq_queue_end(fluid_sequencer_t* seq);
short _fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt);
void _fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type);
int _fluid_seq_queue_process(void* data, unsigned int msec); // callback from timer
static short _fluid_seq_queue_init(fluid_sequencer_t* seq, int nbEvents);
static void _fluid_seq_queue_end(fluid_sequencer_t* seq);
static short _fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt);
static void _fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type);
static int _fluid_seq_queue_process(void* data, unsigned int msec); // callback from timer
static void _fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry);
static void _fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* temp);
static void _fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq);
static void _fluid_free_evt_queue(fluid_evt_entry** first, fluid_evt_entry** last);
/* API implementation */
/**
* Legacy call to new_fluid_sequencer to provide backwards compatibility.
* Please use new_fluid_sequencer2 instead.
* @deprecated
* Create a new sequencer object which uses the system timer. Use
* new_fluid_sequencer2() to specify whether the system timer or
* fluid_sequencer_process() is used to advance the sequencer.
* @return New sequencer instance
*/
fluid_sequencer_t*
new_fluid_sequencer()
new_fluid_sequencer (void)
{
return new_fluid_sequencer2(1);
return new_fluid_sequencer2 (TRUE);
}
/**
* Create a new sequencer object.
* @param useSystemTimer if this parameter is non-zero, sequencer will advance
* at the rate of the computer's system clock. If zero, call fluid_sequencer_process
* to advance the sequencer.
* @param use_system_timer If TRUE, sequencer will advance at the rate of the
* system clock. If FALSE, call fluid_sequencer_process() to advance
* the sequencer.
* @return New sequencer instance
* @since 1.1.0
*/
fluid_sequencer_t*
new_fluid_sequencer2(int useSystemTimer)
new_fluid_sequencer2 (int use_system_timer)
{
fluid_sequencer_t* seq;
@ -116,7 +121,7 @@ new_fluid_sequencer2(int useSystemTimer)
FLUID_MEMSET(seq, 0, sizeof(fluid_sequencer_t));
seq->scale = 1000; // default value
seq->useSystemTimer = useSystemTimer ? TRUE : FALSE;
seq->useSystemTimer = use_system_timer ? TRUE : FALSE;
seq->startMs = seq->useSystemTimer ? fluid_curtime() : 0;
seq->clients = NULL;
seq->clientsID = 0;
@ -142,8 +147,12 @@ new_fluid_sequencer2(int useSystemTimer)
return(seq);
}
/**
* Free a sequencer object.
* @param seq Sequencer to delete
*/
void
delete_fluid_sequencer(fluid_sequencer_t* seq)
delete_fluid_sequencer (fluid_sequencer_t* seq)
{
if (seq == NULL) {
@ -179,11 +188,13 @@ delete_fluid_sequencer(fluid_sequencer_t* seq)
}
/**
* @return 1 if system timers are enabled, or 0 if system timers are disabled.
* Check if a sequencer is using the system timer or not.
* @param seq Sequencer object
* @return TRUE if system timer is being used, FALSE otherwise.
* @since 1.1.0
*/
int
fluid_sequencer_get_useSystemTimer(fluid_sequencer_t* seq)
fluid_sequencer_get_use_system_timer (fluid_sequencer_t* seq)
{
return seq->useSystemTimer ? 1 : 0;
}
@ -216,12 +227,20 @@ fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...)
return;
}
/**
* Clear sequencer trace buffer.
* @param seq Sequencer object
*/
void
fluid_seq_cleartrace(fluid_sequencer_t* seq)
{
seq->traceptr = seq->tracebuf;
}
/**
* Get sequencer trace buffer.
* @param seq Sequencer object
*/
char *
fluid_seq_gettrace(fluid_sequencer_t* seq)
{
@ -235,22 +254,34 @@ void fluid_seq_dotrace(fluid_sequencer_t* seq, char *fmt, ...) {}
/* clients */
short fluid_sequencer_register_client(fluid_sequencer_t* seq, char* name,
fluid_event_callback_t callback, void* data) {
/**
* Register a sequencer client.
* @param seq Sequencer object
* @param name Name of sequencer client
* @param callback Sequencer client callback or NULL for a source client.
* @param data User data to pass to the \a callback
* @return Unique sequencer ID or #FLUID_FAILED on error
*
* Clients can be sources or destinations of events. Sources don't need to
* register a callback.
*/
short
fluid_sequencer_register_client (fluid_sequencer_t* seq, char* name,
fluid_event_callback_t callback, void* data)
{
fluid_sequencer_client_t * client;
char * nameCopy;
client = FLUID_NEW(fluid_sequencer_client_t);
if (client == NULL) {
fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
return -1;
return FLUID_FAILED;
}
nameCopy = FLUID_STRDUP(name);
if (nameCopy == NULL) {
fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
return -1;
return FLUID_FAILED;
}
seq->clientsID++;
@ -265,8 +296,13 @@ short fluid_sequencer_register_client(fluid_sequencer_t* seq, char* name,
return (client->id);
}
/** Unregister a previously registered client. */
void fluid_sequencer_unregister_client(fluid_sequencer_t* seq, short id)
/**
* Unregister a previously registered client.
* @param seq Sequencer object
* @param id Client ID as returned by fluid_sequencer_register_client().
*/
void
fluid_sequencer_unregister_client (fluid_sequencer_t* seq, short id)
{
fluid_list_t *tmp;
fluid_event_t* evt;
@ -302,27 +338,45 @@ void fluid_sequencer_unregister_client(fluid_sequencer_t* seq, short id)
return;
}
int fluid_sequencer_count_clients(fluid_sequencer_t* seq)
/**
* Count a sequencers registered clients.
* @param seq Sequencer object
* @return Count of sequencer clients.
*/
int
fluid_sequencer_count_clients(fluid_sequencer_t* seq)
{
if (seq->clients == NULL)
return 0;
return fluid_list_size(seq->clients);
}
/** Returns the id of a registered client. */
short fluid_sequencer_get_client_id(fluid_sequencer_t* seq, int index)
/**
* Get a client ID from its index (order in which it was registered).
* @param seq Sequencer object
* @param index Index of register client
* @return Client ID or #FLUID_FAILED if not found
*/
short fluid_sequencer_get_client_id (fluid_sequencer_t* seq, int index)
{
fluid_list_t *tmp = fluid_list_nth(seq->clients, index);
if (tmp == NULL) {
return -1;
return FLUID_FAILED;
} else {
fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
return client->id;
}
}
/** Returns the name of a registered client. */
char* fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id)
/**
* Get the name of a registered client.
* @param seq Sequencer object
* @param id Client ID
* @return Client name or NULL if not found. String is internal and should not
* be modified or freed.
*/
char *
fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id)
{
fluid_list_t *tmp;
@ -341,11 +395,18 @@ char* fluid_sequencer_get_client_name(fluid_sequencer_t* seq, int id)
return NULL;
}
int fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id)
/**
* Check if a client is a destination client.
* @param seq Sequencer object
* @param id Client ID
* @return TRUE if client is a destination client, FALSE otherwise or if not found
*/
int
fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id)
{
fluid_list_t *tmp;
if (seq->clients == NULL) return 0;
if (seq->clients == NULL) return FALSE;
tmp = seq->clients;
while (tmp) {
@ -356,11 +417,17 @@ int fluid_sequencer_client_is_dest(fluid_sequencer_t* seq, int id)
tmp = tmp->next;
}
return 0;
return FALSE;
}
/* sending events */
void fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt)
/**
* Send an event immediately.
* @param seq Sequencer object
* @param evt Event to send (copied)
*/
/* Event not actually copied, but since its used immediately it virtually is. */
void
fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt)
{
short destID = fluid_event_get_dest(evt);
@ -379,9 +446,18 @@ void fluid_sequencer_send_now(fluid_sequencer_t* seq, fluid_event_t* evt)
}
}
/**
* Schedule an event for sending at a later time.
* @param seq Sequencer object
* @param evt Event to send
* @param time Time value in ticks (in milliseconds with the default time scale of 1000).
* @param absolute TRUE if \a time is absolute sequencer time (time since sequencer
* creation), FALSE if relative to current time.
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*/
int
fluid_sequencer_send_at(fluid_sequencer_t* seq, fluid_event_t* evt, unsigned int time, int absolute)
fluid_sequencer_send_at (fluid_sequencer_t* seq, fluid_event_t* evt,
unsigned int time, int absolute)
{
unsigned int now = fluid_sequencer_get_tick(seq);
@ -392,25 +468,20 @@ fluid_sequencer_send_at(fluid_sequencer_t* seq, fluid_event_t* evt, unsigned int
/* time stamp event */
fluid_event_set_time(evt, time);
/* process late */
/* Commented out for thread safety - send_at must go via the queue */
/* if (time < now) {
fluid_sequencer_send_now(seq, evt);
return 0;
}*/
/* process now */
/* if (time == now) {
fluid_sequencer_send_now(seq, evt);
return 0;
}*/
/* queue for processing later */
return _fluid_seq_queue_pre_insert(seq, evt);
}
/**
* Remove events from the event queue.
* @param seq Sequencer object
* @param source Source client ID to match or -1 for wildcard
* @param dest Destination client ID to match or -1 for wildcard
* @param type Event type to match or -1 for wildcard (#fluid_seq_event_type)
*/
void
fluid_sequencer_remove_events(fluid_sequencer_t* seq, short source, short dest, int type)
fluid_sequencer_remove_events (fluid_sequencer_t* seq, short source,
short dest, int type)
{
_fluid_seq_queue_pre_remove(seq, source, dest, type);
}
@ -419,7 +490,14 @@ fluid_sequencer_remove_events(fluid_sequencer_t* seq, short source, short dest,
/*************************************
time
**************************************/
unsigned int fluid_sequencer_get_tick(fluid_sequencer_t* seq)
/**
* Get the current tick of a sequencer.
* @param seq Sequencer object
* @return Current tick value
*/
unsigned int
fluid_sequencer_get_tick (fluid_sequencer_t* seq)
{
unsigned int absMs = seq->useSystemTimer ? (int) fluid_curtime() : g_atomic_int_get(&seq->currentMs);
double nowFloat;
@ -429,7 +507,17 @@ unsigned int fluid_sequencer_get_tick(fluid_sequencer_t* seq)
return now;
}
void fluid_sequencer_set_time_scale(fluid_sequencer_t* seq, double scale)
/**
* Set the time scale of a sequencer.
* @param seq Sequencer object
* @param scale Sequencer scale value in ticks per second
* (default is 1000 for 1 tick per millisecond, max is 1000.0)
*
* If there are already scheduled events in the sequencer and the scale is changed
* the events are adjusted accordingly.
*/
void
fluid_sequencer_set_time_scale (fluid_sequencer_t* seq, double scale)
{
if (scale <= 0) {
fluid_log(FLUID_WARN, "sequencer: scale <= 0 : %f\n", scale);
@ -473,9 +561,13 @@ void fluid_sequencer_set_time_scale(fluid_sequencer_t* seq, double scale)
}
}
/** Set the conversion from tick to absolute time (ticks per
second). */
double fluid_sequencer_get_time_scale(fluid_sequencer_t* seq)
/**
* Get a sequencer's time scale.
* @param seq Sequencer object.
* @return Time scale value in ticks per second.
*/
double
fluid_sequencer_get_time_scale(fluid_sequencer_t* seq)
{
return seq->scale;
}
@ -555,18 +647,11 @@ double fluid_sequencer_get_time_scale(fluid_sequencer_t* seq)
*/
void _fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry);
void _fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* temp);
void _fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq);
void _fluid_free_evt_queue(fluid_evt_entry** first, fluid_evt_entry** last);
/********************/
/* API */
/********************/
short
static short
_fluid_seq_queue_init(fluid_sequencer_t* seq, int maxEvents)
{
seq->heap = _fluid_evt_heap_init(maxEvents);
@ -595,7 +680,7 @@ _fluid_seq_queue_init(fluid_sequencer_t* seq, int maxEvents)
return (0);
}
void
static void
_fluid_seq_queue_end(fluid_sequencer_t* seq)
{
int i;
@ -628,10 +713,10 @@ _fluid_seq_queue_end(fluid_sequencer_t* seq)
/* queue management */
/********************/
/* create event_entry and append to the preQueue */
/* may be called from the main thread (usually) but also recursively
from the queue thread, when a callback itself does an insert... */
short
/* Create event_entry and append to the preQueue.
* May be called from the main thread (usually) but also recursively
* from the queue thread, when a callback itself does an insert... */
static short
_fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt)
{
fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap);
@ -660,10 +745,10 @@ _fluid_seq_queue_pre_insert(fluid_sequencer_t* seq, fluid_event_t * evt)
return (0);
}
/* create event_entry and append to the preQueue */
/* may be called from the main thread (usually) but also recursively
from the queue thread, when a callback itself does an insert... */
void
/* Create event_entry and append to the preQueue.
* May be called from the main thread (usually) but also recursively
* from the queue thread, when a callback itself does an insert... */
static void
_fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int type)
{
fluid_evt_entry * evtentry = _fluid_seq_heap_get_free(seq->heap);
@ -697,7 +782,7 @@ _fluid_seq_queue_pre_remove(fluid_sequencer_t* seq, short src, short dest, int t
return;
}
void
static void
_fluid_free_evt_queue(fluid_evt_entry** first, fluid_evt_entry** last)
{
fluid_evt_entry* tmp2;
@ -713,12 +798,8 @@ _fluid_free_evt_queue(fluid_evt_entry** first, fluid_evt_entry** last)
}
}
/***********************
* callback from timer
* (may be in a different thread, or in an interrupt)
*
***********************/
int
/* Callback from timer (may be in a different thread, or in an interrupt) */
static int
_fluid_seq_queue_process(void* data, unsigned int msec)
{
fluid_sequencer_t* seq = (fluid_sequencer_t *)data;
@ -728,8 +809,9 @@ _fluid_seq_queue_process(void* data, unsigned int msec)
}
/**
* Advance sequencer. Do not use if you created the sequencer with useSystemTimer enabled.
* @param msec the number of milliseconds (compared to when the sequencer was created).
* Advance a sequencer that isn't using the system timer.
* @param seq Sequencer object
* @param msec Time to advance sequencer to (absolute time since sequencer start).
* @since 1.1.0
*/
void
@ -768,8 +850,8 @@ fluid_sequencer_process(fluid_sequencer_t* seq, unsigned int msec)
}
void
#if 0
static void
_fluid_seq_queue_print_later(fluid_sequencer_t* seq)
{
int count = 0;
@ -785,9 +867,9 @@ _fluid_seq_queue_print_later(fluid_sequencer_t* seq)
}
printf("queueLater: Total of %i events\n", count);
}
#endif
void
static void
_fluid_seq_queue_insert_queue0(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int cell)
{
if (seq->queue0[cell][1] == NULL) {
@ -799,7 +881,7 @@ _fluid_seq_queue_insert_queue0(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int
tmp->next = NULL;
}
void
static void
_fluid_seq_queue_insert_queue1(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int cell)
{
if (seq->queue1[cell][1] == NULL) {
@ -811,7 +893,7 @@ _fluid_seq_queue_insert_queue1(fluid_sequencer_t* seq, fluid_evt_entry* tmp, int
tmp->next = NULL;
}
void
static void
_fluid_seq_queue_insert_queue_later(fluid_sequencer_t* seq, fluid_evt_entry* evtentry)
{
fluid_evt_entry* prev;
@ -851,7 +933,7 @@ _fluid_seq_queue_insert_queue_later(fluid_sequencer_t* seq, fluid_evt_entry* evt
prev->next = evtentry;
}
void
static void
_fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry)
{
/* time is relative to seq origin, in ticks */
@ -898,7 +980,7 @@ _fluid_seq_queue_insert_entry(fluid_sequencer_t* seq, fluid_evt_entry * evtentry
}
}
int
static int
_fluid_seq_queue_matchevent(fluid_event_t* evt, int templType, short templSrc, short templDest)
{
int eventType;
@ -931,7 +1013,7 @@ _fluid_seq_queue_matchevent(fluid_event_t* evt, int templType, short templSrc, s
return 0;
}
void
static void
_fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry* templ)
{
/* we walk everything : this is slow, but that is life */
@ -1032,7 +1114,7 @@ _fluid_seq_queue_remove_entries_matching(fluid_sequencer_t* seq, fluid_evt_entry
}
}
void
static void
_fluid_seq_queue_send_cell_events(fluid_sequencer_t* seq, int cellNb)
{
fluid_evt_entry* next;
@ -1051,7 +1133,7 @@ _fluid_seq_queue_send_cell_events(fluid_sequencer_t* seq, int cellNb)
seq->queue0[cellNb][1] = NULL;
}
void
static void
_fluid_seq_queue_slide(fluid_sequencer_t* seq)
{
short i;
@ -1108,7 +1190,7 @@ _fluid_seq_queue_slide(fluid_sequencer_t* seq)
seq->queueLater = tmp;
}
void
static void
_fluid_seq_queue_send_queued_events(fluid_sequencer_t* seq)
{
unsigned int nowTicks = fluid_sequencer_get_tick(seq);

View file

@ -49,9 +49,7 @@ typedef struct _fluid_seqbind_t fluid_seqbind_t;
int fluid_seqbind_timer_callback(void* data, unsigned int msec);
void fluid_seq_fluidsynth_callback(unsigned int time, fluid_event_t* event, fluid_sequencer_t* seq, void* data);
/**
* Proper cleanup of the seqbind struct.
*/
/* Proper cleanup of the seqbind struct. */
void
delete_fluid_seqbind(fluid_seqbind_t* seqbind)
{
@ -73,19 +71,21 @@ delete_fluid_seqbind(fluid_seqbind_t* seqbind)
}
/**
* Registers fluidsynth as a client of the given sequencer.
* The fluidsynth is registered with the name "fluidsynth".
* @returns the fluidsynth destID in the sequencer, or -1 if function failed.
* Registers a synthesizer as a destination client of the given sequencer.
* The \a synth is registered with the name "fluidsynth".
* @param seq Sequencer instance
* @param synth Synthesizer instance
* @returns Sequencer client ID, or #FLUID_FAILED on error.
*/
short
fluid_sequencer_register_fluidsynth(fluid_sequencer_t* seq, fluid_synth_t* synth)
fluid_sequencer_register_fluidsynth (fluid_sequencer_t* seq, fluid_synth_t* synth)
{
fluid_seqbind_t* seqbind;
seqbind = FLUID_NEW(fluid_seqbind_t);
if (seqbind == NULL) {
fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
return -1;
return FLUID_FAILED;
}
seqbind->synth = synth;
@ -94,13 +94,13 @@ fluid_sequencer_register_fluidsynth(fluid_sequencer_t* seq, fluid_synth_t* synth
seqbind->client_id = -1;
/* set up the sample timer */
if (!fluid_sequencer_get_useSystemTimer(seq)) {
if (!fluid_sequencer_get_use_system_timer(seq)) {
seqbind->sample_timer =
new_fluid_sample_timer(synth, fluid_seqbind_timer_callback, (void *) seqbind);
if (seqbind->sample_timer == NULL) {
fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
delete_fluid_seqbind(seqbind);
return -1;
return FLUID_FAILED;
}
}
@ -109,7 +109,7 @@ fluid_sequencer_register_fluidsynth(fluid_sequencer_t* seq, fluid_synth_t* synth
fluid_sequencer_register_client(seq, "fluidsynth", fluid_seq_fluidsynth_callback, (void *)seqbind);
if (seqbind->client_id == -1) {
delete_fluid_seqbind(seqbind);
return -1;
return FLUID_FAILED;
}
return seqbind->client_id;
@ -277,9 +277,9 @@ static int get_fluidsynth_dest(fluid_sequencer_t* seq)
/**
* Transforms an incoming midi event (from a midi driver or midi router) to a
* sequencer event and adds it to the sequencer queue for sending as soon as possible.
* @param data the sequencer, must be a valid fluid_sequencer_t
* @param event midi event
* @return FLUID_OK or FLUID_FAILED
* @param data The sequencer, must be a valid #fluid_sequencer_t
* @param event MIDI event
* @return #FLUID_OK or #FLUID_FAILED
* @since 1.1.0
*/
int

View file

@ -699,7 +699,7 @@ fluid_settings_setstr(fluid_settings_t* settings, char* name, char* str)
* @param name a setting's name
* @param str Caller supplied buffer to copy string value to
* @param len Size of 'str' buffer (no more than len bytes will be written, which
* will always include a '\0' terminator)
* will always include a zero terminator)
* @return 1 if the value exists, 0 otherwise
* @since 1.1.0
*

View file

@ -2253,7 +2253,7 @@ fluid_synth_pitch_wheel_sens_LOCAL(fluid_synth_t* synth, int chan, int val)
* @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param pval Location to store pitch wheel sensitivity value in semitones
* @return FLUID_OK on success, FLUID_FAILED otherwise
* @since: ?? Seems it was added sometime AFTER v1.0 API freeze.
* @since Sometime AFTER v1.0 API freeze.
*/
int
fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval)

View file

@ -186,7 +186,7 @@ fluid_log_config(void)
* @param level Log level (#fluid_log_level).
* @param fmt Printf style format string for log message
* @param ... Arguments for printf 'fmt' message string
* @return Always returns -1
* @return Always returns #FLUID_FAILED
*/
int
fluid_log(int level, char* fmt, ...)
@ -286,10 +286,13 @@ fluid_error()
return fluid_errbuf;
}
/*
/**
* Check if a file is a MIDI file.
* @param filename Path to the file to check
* @return TRUE if it could be a MIDI file, FALSE otherwise
*
* fluid_is_midifile
* The current implementation only checks for the "MThd" header in the file.
* It is useful only to distinguish between SoundFont and MIDI files.
*/
int
fluid_is_midifile(char* filename)
@ -309,9 +312,13 @@ fluid_is_midifile(char* filename)
return strncmp(id, "MThd", 4) == 0;
}
/*
* fluid_is_soundfont
/**
* Check if a file is a SoundFont file.
* @param filename Path to the file to check
* @return TRUE if it could be a SoundFont, FALSE otherwise
*
* The current implementation only checks for the "RIFF" header in the file.
* It is useful only to distinguish between SoundFont and MIDI files.
*/
int
fluid_is_soundfont(char* filename)

View file

@ -203,19 +203,40 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
return FLUID_OK;
}
void fluid_voice_gen_set(fluid_voice_t* voice, int i, float val)
/**
* Set the value of a generator.
* @param voice Voice instance
* @param i Generator ID (#fluid_gen_type)
* @param val Generator value
*/
void
fluid_voice_gen_set(fluid_voice_t* voice, int i, float val)
{
voice->gen[i].val = val;
voice->gen[i].flags = GEN_SET;
}
void fluid_voice_gen_incr(fluid_voice_t* voice, int i, float val)
/**
* Offset the value of a generator.
* @param voice Voice instance
* @param i Generator ID (#fluid_gen_type)
* @param val Value to add to the existing value
*/
void
fluid_voice_gen_incr(fluid_voice_t* voice, int i, float val)
{
voice->gen[i].val += val;
voice->gen[i].flags = GEN_SET;
}
float fluid_voice_gen_get(fluid_voice_t* voice, int gen)
/**
* Get the value of a generator.
* @param voice Voice instance
* @param gen Generator ID (#fluid_gen_type)
* @return Current generator value
*/
float
fluid_voice_gen_get(fluid_voice_t* voice, int gen)
{
return voice->gen[gen].val;
}
@ -1018,10 +1039,6 @@ calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
}
/*
* fluid_voice_update_param
*
* Purpose:
*
* The value of a generator (gen) has changed. (The different
* generators are listed in fluidsynth.h, or in SF2.01 page 48-49)
* Now the dependent 'voice' parameters are calculated.
@ -1036,6 +1053,14 @@ calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
* NRPN system. _GEN(voice, generator_enumerator) returns the sum
* of all three.
*/
/**
* Update all the synthesis parameters, which depend on generator \a gen.
* @param voice Voice instance
* @param gen Generator id (#fluid_gen_type)
*
* This is only necessary after changing a generator of an already operating voice.
* Most applications will not need this function.
*/
void
fluid_voice_update_param(fluid_voice_t* voice, int gen)
{
@ -1444,7 +1469,10 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
}
/**
* fluid_voice_modulate
* Recalculate voice parameters for a given control.
* @param voice the synthesis voice
* @param cc flag to distinguish between a continous control and a channel control (pitch bend, ...)
* @param ctrl the control number
*
* In this implementation, I want to make sure that all controllers
* are event based: the parameter values of the DSP algorithm should
@ -1464,12 +1492,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
*
* - For every changed generator, convert its value to the correct
* unit of the corresponding DSP parameter
*
* @fn int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl, int val)
* @param voice the synthesis voice
* @param cc flag to distinguish between a continous control and a channel control (pitch bend, ...)
* @param ctrl the control number
* */
*/
int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl)
{
int i, k;
@ -1510,8 +1533,6 @@ int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl)
}
/**
* fluid_voice_modulate_all
*
* Update all the modulators. This function is called after a
* ALL_CTRL_OFF MIDI message has been received (CC 121).
*
@ -1670,16 +1691,15 @@ fluid_voice_off(fluid_voice_t* voice)
return FLUID_OK;
}
/*
* fluid_voice_add_mod
*
* Adds a modulator to the voice. "mode" indicates, what to do, if
* an identical modulator exists already.
*
* mode == FLUID_VOICE_ADD: Identical modulators on preset level are added
* mode == FLUID_VOICE_OVERWRITE: Identical modulators on instrument level are overwritten
* mode == FLUID_VOICE_DEFAULT: This is a default modulator, there can be no identical modulator.
* Don't check.
/**
* Adds a modulator to the voice.
* @param voice Voice instance
* @param mod Modulator info (copied)
* @param mode Determines how to handle an existing identical modulator
* #FLUID_VOICE_ADD to add (offset) the modulator amounts,
* #FLUID_VOICE_OVERWRITE to replace the modulator,
* #FLUID_VOICE_DEFAULT when adding a default modulator - no duplicate should
* exist so don't check.
*/
void
fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
@ -1735,11 +1755,32 @@ fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
}
}
/**
* Get the unique ID of the noteon-event.
* @param voice Voice instance
* @return Note on unique ID
*
* A SoundFont loader may store the voice processes it has created for
* real-time control during the operation of a voice (for example: parameter
* changes in SoundFont editor). The synth uses a pool of voices, which are
* 'recycled' and never deallocated.
*
* Before modifying an existing voice, check
* - that its state is still 'playing'
* - that the ID is still the same
*
* Otherwise the voice has finished playing.
*/
unsigned int fluid_voice_get_id(fluid_voice_t* voice)
{
return voice->id;
}
/**
* Check if a voice is still playing.
* @param voice Voice instance
* @return TRUE if playing, FALSE otherwise
*/
int fluid_voice_is_playing(fluid_voice_t* voice)
{
return _PLAYING(voice);
@ -1982,7 +2023,19 @@ int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain)
* - Calculate, what factor will make the loop inaudible
* - Store in sample
*/
int fluid_voice_optimize_sample(fluid_sample_t* s)
/**
* Calculate the peak volume of a sample for voice off optimization.
* @param s Sample to optimize
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* If the peak volume during the loop is known, then the voice can
* be released earlier during the release phase. Otherwise, the
* voice will operate (inaudibly), until the envelope is at the
* nominal turnoff point. So it's a good idea to call
* fluid_voice_optimize_sample() on each sample once.
*/
int
fluid_voice_optimize_sample(fluid_sample_t* s)
{
signed short peak_max = 0;
signed short peak_min = 0;

View file

@ -154,12 +154,6 @@ typedef double fluid_real_t;
#endif
typedef enum {
FLUID_OK = 0,
FLUID_FAILED = -1
} fluid_status;
#if defined(WIN32)
typedef SOCKET fluid_socket_t;
#else