diff --git a/doc/recent_changes.txt b/doc/recent_changes.txt index 33c7a12c..c564db83 100644 --- a/doc/recent_changes.txt +++ b/doc/recent_changes.txt @@ -1,6 +1,12 @@ /*! \page RecentChanges Recent Changes +\section NewIn2_2_7 What's new in 2.2.7? + +- Most getter functions of the MIDI event API are now const correct +- fluid_event_from_midi_event() has been added + + \section NewIn2_2_0 What's new in 2.2.0? - #fluid_file_callbacks_t now uses long long as file-offset type (see #fluid_long_long_t).This is a breaking change, which allows to load SoundFonts bigger than 2GiB on Windows. This change required to bump fluidsynth's SOVERSION. diff --git a/include/fluidsynth/event.h b/include/fluidsynth/event.h index e50f974f..643f6c52 100644 --- a/include/fluidsynth/event.h +++ b/include/fluidsynth/event.h @@ -117,6 +117,7 @@ FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t *evt); FLUIDSYNTH_API void fluid_event_unregistering(fluid_event_t *evt); FLUIDSYNTH_API void fluid_event_scale(fluid_event_t *evt, double new_scale); +FLUIDSYNTH_API int fluid_event_from_midi_event(fluid_event_t *, const fluid_midi_event_t *); /* Accessing event data */ FLUIDSYNTH_API int fluid_event_get_type(fluid_event_t *evt); diff --git a/include/fluidsynth/midi.h b/include/fluidsynth/midi.h index 067db84e..cc3e435b 100644 --- a/include/fluidsynth/midi.h +++ b/include/fluidsynth/midi.h @@ -114,20 +114,20 @@ FLUIDSYNTH_API void delete_fluid_midi_event(fluid_midi_event_t *event); /** @endlifecycle */ FLUIDSYNTH_API int fluid_midi_event_set_type(fluid_midi_event_t *evt, int type); -FLUIDSYNTH_API int fluid_midi_event_get_type(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_type(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan); -FLUIDSYNTH_API int fluid_midi_event_get_channel(fluid_midi_event_t *evt); -FLUIDSYNTH_API int fluid_midi_event_get_key(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_channel(const fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_key(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_key(fluid_midi_event_t *evt, int key); -FLUIDSYNTH_API int fluid_midi_event_get_velocity(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_velocity(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int vel); -FLUIDSYNTH_API int fluid_midi_event_get_control(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_control(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_control(fluid_midi_event_t *evt, int ctrl); -FLUIDSYNTH_API int fluid_midi_event_get_value(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_value(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_value(fluid_midi_event_t *evt, int val); -FLUIDSYNTH_API int fluid_midi_event_get_program(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_program(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_program(fluid_midi_event_t *evt, int val); -FLUIDSYNTH_API int fluid_midi_event_get_pitch(fluid_midi_event_t *evt); +FLUIDSYNTH_API int fluid_midi_event_get_pitch(const fluid_midi_event_t *evt); FLUIDSYNTH_API int fluid_midi_event_set_pitch(fluid_midi_event_t *evt, int val); FLUIDSYNTH_API int fluid_midi_event_set_sysex(fluid_midi_event_t *evt, void *data, int size, int dynamic); diff --git a/include/fluidsynth/seqbind.h b/include/fluidsynth/seqbind.h index ddf1cb9d..b8fd1a40 100644 --- a/include/fluidsynth/seqbind.h +++ b/include/fluidsynth/seqbind.h @@ -34,8 +34,8 @@ extern "C" { */ FLUIDSYNTH_API fluid_seq_id_t fluid_sequencer_register_fluidsynth(fluid_sequencer_t *seq, fluid_synth_t *synth); -FLUIDSYNTH_API int -fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event); +FLUIDSYNTH_API +int fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event); /* @} */ #ifdef __cplusplus diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index cab651b8..89271cf3 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -1106,7 +1106,7 @@ delete_fluid_midi_event(fluid_midi_event_t *evt) * @return Event type field (MIDI status byte without channel) */ int -fluid_midi_event_get_type(fluid_midi_event_t *evt) +fluid_midi_event_get_type(const fluid_midi_event_t *evt) { return evt->type; } @@ -1130,7 +1130,7 @@ fluid_midi_event_set_type(fluid_midi_event_t *evt, int type) * @return Channel field */ int -fluid_midi_event_get_channel(fluid_midi_event_t *evt) +fluid_midi_event_get_channel(const fluid_midi_event_t *evt) { return evt->channel; } @@ -1154,7 +1154,7 @@ fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan) * @return MIDI note number (0-127) */ int -fluid_midi_event_get_key(fluid_midi_event_t *evt) +fluid_midi_event_get_key(const fluid_midi_event_t *evt) { return evt->param1; } @@ -1178,7 +1178,7 @@ fluid_midi_event_set_key(fluid_midi_event_t *evt, int v) * @return MIDI velocity number (0-127) */ int -fluid_midi_event_get_velocity(fluid_midi_event_t *evt) +fluid_midi_event_get_velocity(const fluid_midi_event_t *evt) { return evt->param2; } @@ -1202,7 +1202,7 @@ fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int v) * @return MIDI control number */ int -fluid_midi_event_get_control(fluid_midi_event_t *evt) +fluid_midi_event_get_control(const fluid_midi_event_t *evt) { return evt->param1; } @@ -1226,7 +1226,7 @@ fluid_midi_event_set_control(fluid_midi_event_t *evt, int v) * @return Value field */ int -fluid_midi_event_get_value(fluid_midi_event_t *evt) +fluid_midi_event_get_value(const fluid_midi_event_t *evt) { return evt->param2; } @@ -1250,7 +1250,7 @@ fluid_midi_event_set_value(fluid_midi_event_t *evt, int v) * @return MIDI program number (0-127) */ int -fluid_midi_event_get_program(fluid_midi_event_t *evt) +fluid_midi_event_get_program(const fluid_midi_event_t *evt) { return evt->param1; } @@ -1274,7 +1274,7 @@ fluid_midi_event_set_program(fluid_midi_event_t *evt, int val) * @return Pitch value (14 bit value, 0-16383, 8192 is center) */ int -fluid_midi_event_get_pitch(fluid_midi_event_t *evt) +fluid_midi_event_get_pitch(const fluid_midi_event_t *evt) { return evt->param1; } diff --git a/src/midi/fluid_seqbind.c b/src/midi/fluid_seqbind.c index eb922297..9ec06f20 100644 --- a/src/midi/fluid_seqbind.c +++ b/src/midi/fluid_seqbind.c @@ -367,64 +367,20 @@ static fluid_seq_id_t get_fluidsynth_dest(fluid_sequencer_t *seq) * * @since 1.1.0 */ -int -fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event) +int fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event) { fluid_event_t evt; fluid_sequencer_t *seq; - int chan; fluid_return_val_if_fail(data != NULL, FLUID_FAILED); fluid_return_val_if_fail(event != NULL, FLUID_FAILED); - seq = (fluid_sequencer_t *) data; - chan = fluid_midi_event_get_channel(event); + seq = (fluid_sequencer_t *)data; fluid_event_clear(&evt); + fluid_event_from_midi_event(&evt, event); fluid_event_set_dest(&evt, get_fluidsynth_dest(seq)); - switch(fluid_midi_event_get_type(event)) - { - case NOTE_OFF: - fluid_event_noteoff(&evt, chan, (short)fluid_midi_event_get_key(event)); - break; - - case NOTE_ON: - fluid_event_noteon(&evt, fluid_midi_event_get_channel(event), - (short)fluid_midi_event_get_key(event), (short)fluid_midi_event_get_velocity(event)); - break; - - case CONTROL_CHANGE: - fluid_event_control_change(&evt, chan, (short)fluid_midi_event_get_control(event), - (short)fluid_midi_event_get_value(event)); - break; - - case PROGRAM_CHANGE: - fluid_event_program_change(&evt, chan, (short)fluid_midi_event_get_program(event)); - break; - - case PITCH_BEND: - fluid_event_pitch_bend(&evt, chan, fluid_midi_event_get_pitch(event)); - break; - - case CHANNEL_PRESSURE: - fluid_event_channel_pressure(&evt, chan, (short)fluid_midi_event_get_program(event)); - break; - - case KEY_PRESSURE: - fluid_event_key_pressure(&evt, chan, - (short)fluid_midi_event_get_key(event), - (short)fluid_midi_event_get_value(event)); - break; - - case MIDI_SYSTEM_RESET: - fluid_event_system_reset(&evt); - break; - - default: /* Not yet implemented */ - return FLUID_FAILED; - } - /* Schedule for sending at next call to fluid_sequencer_process */ return fluid_sequencer_send_at(seq, &evt, 0, 0); } diff --git a/src/synth/fluid_event.c b/src/synth/fluid_event.c index ddc6aa8b..48b781bd 100644 --- a/src/synth/fluid_event.c +++ b/src/synth/fluid_event.c @@ -30,6 +30,7 @@ #include "fluid_event.h" #include "fluidsynth_priv.h" +#include "fluid_midi.h" /*************************************************************** * @@ -577,7 +578,88 @@ fluid_event_system_reset(fluid_event_t *evt) evt->type = FLUID_SEQ_SYSTEMRESET; } +/** + * Transforms an incoming MIDI event (from a MIDI driver or MIDI router) to a + * sequencer event. + * + * @param evt Sequencer event structure + * @param event MIDI event + * @return #FLUID_OK or #FLUID_FAILED + * + * @note This function copies the fields of the MIDI event into the provided + * sequencer event. Calling applications must create the sequencer event and set + * additional fields such as the source and destination of the sequencer event. + * + * @code{.cpp} + * // ... get MIDI event, e.g. using player_callback() + * + * // Send MIDI event to sequencer to play + * fluid_event_t *evt = new_fluid_event(); + * fluid_event_set_source(evt, -1); + * fluid_event_set_dest(evt, seqid); + * fluid_event_from_midi_event(evt, event); + * fluid_sequencer_send_at(sequencer, evt, 50, 0); // relative time + * delete_fluid_event(evt); + * @endcode + * + * @since 2.2.7 + */ +int fluid_event_from_midi_event(fluid_event_t *evt, const fluid_midi_event_t *event) +{ + int chan; + fluid_return_val_if_fail(event != NULL, FLUID_FAILED); + chan = fluid_midi_event_get_channel(event); + + switch (fluid_midi_event_get_type(event)) + { + case NOTE_OFF: + fluid_event_noteoff(evt, chan, (short)fluid_midi_event_get_key(event)); + break; + + case NOTE_ON: + fluid_event_noteon(evt, + fluid_midi_event_get_channel(event), + (short)fluid_midi_event_get_key(event), + (short)fluid_midi_event_get_velocity(event)); + break; + + case CONTROL_CHANGE: + fluid_event_control_change(evt, + chan, + (short)fluid_midi_event_get_control(event), + (short)fluid_midi_event_get_value(event)); + break; + + case PROGRAM_CHANGE: + fluid_event_program_change(evt, chan, (short)fluid_midi_event_get_program(event)); + break; + + case PITCH_BEND: + fluid_event_pitch_bend(evt, chan, fluid_midi_event_get_pitch(event)); + break; + + case CHANNEL_PRESSURE: + fluid_event_channel_pressure(evt, chan, (short)fluid_midi_event_get_program(event)); + break; + + case KEY_PRESSURE: + fluid_event_key_pressure(evt, + chan, + (short)fluid_midi_event_get_key(event), + (short)fluid_midi_event_get_value(event)); + break; + + case MIDI_SYSTEM_RESET: + fluid_event_system_reset(evt); + break; + + default: /* Not yet implemented */ + return FLUID_FAILED; + } + + return FLUID_OK; +} /* * Accessing event data