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