mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-03-01 15:10:43 +00:00
Merge pull request #1080 from FluidSynth/issue1078
Add a function to create a sequencer event from a midi event
This commit is contained in:
commit
0995727374
7 changed files with 110 additions and 65 deletions
|
@ -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 <span style="color:red">now uses <code>long long</code> as file-offset type (see #fluid_long_long_t).</span><span style="color:red;font-weight:bold">This is a breaking change</span>, which allows to load SoundFonts bigger than 2GiB on Windows. This change required to bump fluidsynth's SOVERSION.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue