mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-01-31 13:40:35 +00:00
MIDI input group
Contains MIDI Driver, MIDI Router, MIDI Player and MIDI Events
This commit is contained in:
parent
bae3dec78a
commit
4185b25d6f
4 changed files with 136 additions and 45 deletions
|
@ -26,12 +26,51 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup MIDI MIDI
|
||||
* @brief Functions for MIDI events, drivers and MIDI file playback.
|
||||
* @defgroup midi_input MIDI Input
|
||||
*
|
||||
* MIDI Input Subsystem
|
||||
*
|
||||
* There are multiple ways to send MIDI events to the synthesizer. They can come
|
||||
* from MIDI files, from external MIDI sequencers or raw MIDI event sources,
|
||||
* can be modified via MIDI routers and also generated manually.
|
||||
*
|
||||
* The interface connecting all sources and sinks of MIDI events in libfluidsynth
|
||||
* is \ref handle_midi_event_func_t.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic callback function for MIDI event handler.
|
||||
*
|
||||
* @param data User defined data pointer
|
||||
* @param event The MIDI event
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* This callback is used to pass MIDI events
|
||||
* - from \ref midi_player, \ref midi_router or \ref midi_driver
|
||||
* - to \ref midi_router via fluid_midi_router_handle_midi_event()
|
||||
* - or to \ref synth via fluid_synth_handle_midi_event().
|
||||
*
|
||||
* Additionally, there is a translation layer to pass MIDI events to
|
||||
* a \ref sequencer via fluid_sequencer_add_midi_event_to_buffer().
|
||||
*/
|
||||
typedef int (*handle_midi_event_func_t)(void *data, fluid_midi_event_t *event);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_events MIDI Events
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Functions to create, modify, query and delete MIDI events.
|
||||
*
|
||||
* These functions are intended to be used in MIDI routers and other filtering
|
||||
* and processing functions in the MIDI event path. If you want to simply
|
||||
* send MIDI messages to the synthesizer, you can use the more convenient
|
||||
* \ref midi_messages interface.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API fluid_midi_event_t *new_fluid_midi_event(void);
|
||||
FLUIDSYNTH_API void delete_fluid_midi_event(fluid_midi_event_t *event);
|
||||
|
||||
|
@ -61,9 +100,20 @@ FLUIDSYNTH_API int fluid_midi_event_set_lyrics(fluid_midi_event_t *evt,
|
|||
void *data, int size, int dynamic);
|
||||
FLUIDSYNTH_API int fluid_midi_event_get_lyrics(fluid_midi_event_t *evt,
|
||||
void **data, int *size);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_router MIDI Router
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Rule based tranformation and filtering of MIDI events.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIDI router rule type.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
typedef enum
|
||||
|
@ -74,24 +124,11 @@ typedef enum
|
|||
FLUID_MIDI_ROUTER_RULE_PITCH_BEND, /**< MIDI pitch bend rule */
|
||||
FLUID_MIDI_ROUTER_RULE_CHANNEL_PRESSURE, /**< MIDI channel pressure rule */
|
||||
FLUID_MIDI_ROUTER_RULE_KEY_PRESSURE, /**< MIDI key pressure rule */
|
||||
#ifndef __DOXYGEN__
|
||||
FLUID_MIDI_ROUTER_RULE_COUNT /**< @internal Total count of rule types @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time!*/
|
||||
#endif
|
||||
FLUID_MIDI_ROUTER_RULE_COUNT /**< @internal Total count of rule types. This symbol
|
||||
is not part of the public API and ABI stability
|
||||
guarantee and may change at any time!*/
|
||||
} fluid_midi_router_rule_type;
|
||||
|
||||
/**
|
||||
* Generic callback function for MIDI events.
|
||||
* @param data User defined data pointer
|
||||
* @param event The MIDI event
|
||||
* @return Should return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* Will be used between
|
||||
* - MIDI driver and MIDI router
|
||||
* - MIDI router and synth
|
||||
* to communicate events.
|
||||
* In the not-so-far future...
|
||||
*/
|
||||
typedef int (*handle_midi_event_func_t)(void *data, fluid_midi_event_t *event);
|
||||
|
||||
FLUIDSYNTH_API fluid_midi_router_t *new_fluid_midi_router(fluid_settings_t *settings,
|
||||
handle_midi_event_func_t handler,
|
||||
|
@ -112,15 +149,43 @@ FLUIDSYNTH_API void fluid_midi_router_rule_set_param2(fluid_midi_router_rule_t *
|
|||
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);
|
||||
/* @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup midi_driver MIDI Driver
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Functions for managing MIDI drivers.
|
||||
*
|
||||
* The available MIDI drivers depend on your platform. See \ref settings_midi for all
|
||||
* available configuration options.
|
||||
*
|
||||
* To create a MIDI driver, you need to specify a source for the MIDI events to be
|
||||
* forwarded to via the \ref fluid_midi_event_t callback. Normally this will be
|
||||
* either a \ref midi_router via fluid_midi_router_handle_midi_event() or the synthesizer
|
||||
* via fluid_synth_handle_midi_event().
|
||||
*
|
||||
* But you can also write your own handler function that preprocesses the events and
|
||||
* forwards them on to the router or synthesizer instead.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
FLUIDSYNTH_API
|
||||
fluid_midi_driver_t *new_fluid_midi_driver(fluid_settings_t *settings,
|
||||
handle_midi_event_func_t handler,
|
||||
void *event_handler_data);
|
||||
|
||||
FLUIDSYNTH_API void delete_fluid_midi_driver(fluid_midi_driver_t *driver);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
* @defgroup midi_player MIDI Player
|
||||
* @ingroup midi_input
|
||||
*
|
||||
* Parse standard MIDI files and emit MIDI events.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIDI player status enum.
|
||||
|
@ -151,9 +216,6 @@ FLUIDSYNTH_API int fluid_player_get_total_ticks(fluid_player_t *player);
|
|||
FLUIDSYNTH_API int fluid_player_get_bpm(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_get_midi_tempo(fluid_player_t *player);
|
||||
FLUIDSYNTH_API int fluid_player_seek(fluid_player_t *player, int ticks);
|
||||
|
||||
///
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -135,11 +135,14 @@ void fluid_midi_driver_settings(fluid_settings_t *settings)
|
|||
|
||||
/**
|
||||
* Create a new MIDI driver instance.
|
||||
* @param settings Settings used to configure new MIDI driver.
|
||||
*
|
||||
* @param settings Settings used to configure new MIDI driver. See \ref settings_midi for available options.
|
||||
* @param handler MIDI handler callback (for example: fluid_midi_router_handle_midi_event()
|
||||
* for MIDI router)
|
||||
* @param event_handler_data Caller defined data to pass to 'handler'
|
||||
* @return New MIDI driver instance or NULL on error
|
||||
*
|
||||
* Which MIDI driver is actually created depends on the \ref settings_midi_driver option.
|
||||
*/
|
||||
fluid_midi_driver_t *new_fluid_midi_driver(fluid_settings_t *settings, handle_midi_event_func_t handler, void *event_handler_data)
|
||||
{
|
||||
|
|
|
@ -1798,16 +1798,18 @@ fluid_player_add_track(fluid_player_t *player, fluid_track_t *track)
|
|||
}
|
||||
|
||||
/**
|
||||
* Change the MIDI callback function. This is usually set to
|
||||
* fluid_synth_handle_midi_event(), but can optionally be changed
|
||||
* to a user-defined function instead, for intercepting all MIDI
|
||||
* messages sent to the synth. You can also use a midi router as
|
||||
* the callback function to modify the MIDI messages before sending
|
||||
* them to the synth.
|
||||
* Change the MIDI callback function.
|
||||
*
|
||||
* @param player MIDI player instance
|
||||
* @param handler Pointer to callback function
|
||||
* @param handler_data Parameter sent to the callback function
|
||||
* @returns FLUID_OK
|
||||
*
|
||||
* This is usually set to fluid_synth_handle_midi_event(), but can optionally
|
||||
* be changed to a user-defined function instead, for intercepting all MIDI
|
||||
* messages sent to the synth. You can also use a midi router as the callback
|
||||
* function to modify the MIDI messages before sending them to the synth.
|
||||
*
|
||||
* @since 1.1.4
|
||||
*/
|
||||
int
|
||||
|
@ -2140,9 +2142,10 @@ fluid_player_play(fluid_player_t *player)
|
|||
/**
|
||||
* Pauses the MIDI playback.
|
||||
*
|
||||
* It will not rewind to the beginning of the file, use fluid_player_seek() for this purpose.
|
||||
* @param player MIDI player instance
|
||||
* @return Always returns #FLUID_OK
|
||||
*
|
||||
* It will not rewind to the beginning of the file, use fluid_player_seek() for this purpose.
|
||||
*/
|
||||
int
|
||||
fluid_player_stop(fluid_player_t *player)
|
||||
|
@ -2167,15 +2170,17 @@ fluid_player_get_status(fluid_player_t *player)
|
|||
/**
|
||||
* Seek in the currently playing file.
|
||||
*
|
||||
* The actual seek will be performed when the synth calls back the player (i.e. a few
|
||||
* levels above the player's callback set with fluid_player_set_playback_callback()).
|
||||
* If the player's status is #FLUID_PLAYER_PLAYING and a previous seek operation has
|
||||
* not been completed yet, #FLUID_FAILED is returned.
|
||||
* @param player MIDI player instance
|
||||
* @param ticks the position to seek to in the current file
|
||||
* @return #FLUID_FAILED if ticks is negative or after the latest tick of the file
|
||||
* [or, since 2.1.3, if another seek operation is currently in progress],
|
||||
* #FLUID_OK otherwise.
|
||||
*
|
||||
* The actual seek will be performed when the synth calls back the player (i.e. a few
|
||||
* levels above the player's callback set with fluid_player_set_playback_callback()).
|
||||
* If the player's status is #FLUID_PLAYER_PLAYING and a previous seek operation has
|
||||
* not been completed yet, #FLUID_FAILED is returned.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
int fluid_player_seek(fluid_player_t *player, int ticks)
|
||||
|
@ -2210,13 +2215,15 @@ int fluid_player_seek(fluid_player_t *player, int ticks)
|
|||
|
||||
/**
|
||||
* 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 #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.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
int fluid_player_set_loop(fluid_player_t *player, int loop)
|
||||
{
|
||||
|
|
|
@ -68,12 +68,15 @@ struct _fluid_midi_router_rule_t
|
|||
|
||||
|
||||
/**
|
||||
* Create a new midi router. The default rules will pass all events unmodified.
|
||||
* Create a new midi router.
|
||||
*
|
||||
* @param settings Settings used to configure MIDI router
|
||||
* @param handler MIDI event callback.
|
||||
* @param event_handler_data Caller defined data pointer which gets passed to 'handler'
|
||||
* @return New MIDI router instance or NULL on error
|
||||
*
|
||||
* The new router will start with default rules and therefore pass all events unmodified.
|
||||
*
|
||||
* The MIDI handler callback should process the possibly filtered/modified MIDI
|
||||
* events from the MIDI router and forward them on to a synthesizer for example.
|
||||
* The function fluid_synth_handle_midi_event() can be used for \a handle and
|
||||
|
@ -151,10 +154,13 @@ delete_fluid_midi_router(fluid_midi_router_t *router)
|
|||
}
|
||||
|
||||
/**
|
||||
* Set a MIDI router to use default "unity" rules. Such a router will pass all
|
||||
* events unmodified.
|
||||
* Set a MIDI router to use default "unity" rules.
|
||||
*
|
||||
* @param router Router to set to default rules.
|
||||
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* Such a router will pass all events unmodified.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
int
|
||||
|
@ -244,10 +250,13 @@ fluid_midi_router_set_default_rules(fluid_midi_router_t *router)
|
|||
}
|
||||
|
||||
/**
|
||||
* Clear all rules in a MIDI router. Such a router will drop all events until
|
||||
* rules are added.
|
||||
* Clear all rules in a MIDI router.
|
||||
*
|
||||
* @param router Router to clear all rules from
|
||||
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*
|
||||
* An empty router will drop all events until rules are added.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
int
|
||||
|
@ -357,11 +366,13 @@ fluid_midi_router_add_rule(fluid_midi_router_t *router, fluid_midi_router_rule_t
|
|||
|
||||
/**
|
||||
* Create a new MIDI router rule.
|
||||
*
|
||||
* @return Newly allocated router rule or NULL if out of memory.
|
||||
* @since 1.1.0
|
||||
*
|
||||
* The new rule is a "unity" rule which will accept any values and wont modify
|
||||
* them.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fluid_midi_router_rule_t *
|
||||
new_fluid_midi_router_rule(void)
|
||||
|
@ -396,11 +407,13 @@ new_fluid_midi_router_rule(void)
|
|||
|
||||
/**
|
||||
* Free a MIDI router rule.
|
||||
*
|
||||
* @param rule Router rule to free
|
||||
* @since 1.1.0
|
||||
*
|
||||
* Note that rules which have been added to a router are managed by the router,
|
||||
* so this function should seldom be needed.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void
|
||||
delete_fluid_midi_router_rule(fluid_midi_router_rule_t *rule)
|
||||
|
@ -411,12 +424,12 @@ delete_fluid_midi_router_rule(fluid_midi_router_rule_t *rule)
|
|||
|
||||
/**
|
||||
* Set the channel portion of a rule.
|
||||
*
|
||||
* @param rule MIDI router rule
|
||||
* @param min Minimum value for rule match
|
||||
* @param max Maximum value for rule match
|
||||
* @param mul Value which is multiplied by matching event's channel value (1.0 to not modify)
|
||||
* @param add Value which is added to matching event's channel value (0 to not modify)
|
||||
* @since 1.1.0
|
||||
*
|
||||
* The \a min and \a max parameters define a channel range window to match
|
||||
* incoming events to. If \a min is less than or equal to \a max then an event
|
||||
|
@ -426,6 +439,8 @@ delete_fluid_midi_router_rule(fluid_midi_router_rule_t *rule)
|
|||
*
|
||||
* The \a mul and \a add values are used to modify event channel values prior to
|
||||
* sending the event, if the rule matches.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void
|
||||
fluid_midi_router_rule_set_chan(fluid_midi_router_rule_t *rule, int min, int max,
|
||||
|
@ -440,12 +455,12 @@ fluid_midi_router_rule_set_chan(fluid_midi_router_rule_t *rule, int min, int max
|
|||
|
||||
/**
|
||||
* Set the first parameter portion of a rule.
|
||||
*
|
||||
* @param rule MIDI router rule
|
||||
* @param min Minimum value for rule match
|
||||
* @param max Maximum value for rule match
|
||||
* @param mul Value which is multiplied by matching event's 1st parameter value (1.0 to not modify)
|
||||
* @param add Value which is added to matching event's 1st parameter value (0 to not modify)
|
||||
* @since 1.1.0
|
||||
*
|
||||
* The 1st parameter of an event depends on the type of event. For note events
|
||||
* its the MIDI note #, for CC events its the MIDI control number, for program
|
||||
|
@ -464,6 +479,8 @@ fluid_midi_router_rule_set_chan(fluid_midi_router_rule_t *rule, int min, int max
|
|||
*
|
||||
* The \a mul and \a add values are used to modify event 1st parameter values prior to
|
||||
* sending the event, if the rule matches.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void
|
||||
fluid_midi_router_rule_set_param1(fluid_midi_router_rule_t *rule, int min, int max,
|
||||
|
@ -478,12 +495,12 @@ fluid_midi_router_rule_set_param1(fluid_midi_router_rule_t *rule, int min, int m
|
|||
|
||||
/**
|
||||
* Set the second parameter portion of a rule.
|
||||
*
|
||||
* @param rule MIDI router rule
|
||||
* @param min Minimum value for rule match
|
||||
* @param max Maximum value for rule match
|
||||
* @param mul Value which is multiplied by matching event's 2nd parameter value (1.0 to not modify)
|
||||
* @param add Value which is added to matching event's 2nd parameter value (0 to not modify)
|
||||
* @since 1.1.0
|
||||
*
|
||||
* The 2nd parameter of an event depends on the type of event. For note events
|
||||
* its the MIDI velocity, for CC events its the control value and for key pressure
|
||||
|
@ -499,6 +516,8 @@ fluid_midi_router_rule_set_param1(fluid_midi_router_rule_t *rule, int min, int m
|
|||
*
|
||||
* The \a mul and \a add values are used to modify event 2nd parameter values prior to
|
||||
* sending the event, if the rule matches.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void
|
||||
fluid_midi_router_rule_set_param2(fluid_midi_router_rule_t *rule, int min, int max,
|
||||
|
|
Loading…
Reference in a new issue