Merge branch 'poly-pressure' of https://github.com/mawe42/fluidsynth into mawe42-poly-pressure

This commit is contained in:
derselbst 2017-09-10 13:59:07 +02:00
commit 5baecd9db4
9 changed files with 101 additions and 7 deletions

View file

@ -143,3 +143,4 @@ Nick Daly
David Hilvert David Hilvert
Bernat Arlandis i Mañó Bernat Arlandis i Mañó
Sven Meier Sven Meier
Marcus Weseloh

View file

@ -56,6 +56,7 @@ enum fluid_seq_event_type {
FLUID_SEQ_TIMER, /**< Timer event (useful for giving a callback at a certain time) */ FLUID_SEQ_TIMER, /**< Timer event (useful for giving a callback at a certain time) */
FLUID_SEQ_ANYCONTROLCHANGE, /**< DOCME (used for remove_events only) */ FLUID_SEQ_ANYCONTROLCHANGE, /**< DOCME (used for remove_events only) */
FLUID_SEQ_CHANNELPRESSURE, /**< Channel aftertouch event @since 1.1.0 */ FLUID_SEQ_CHANNELPRESSURE, /**< Channel aftertouch event @since 1.1.0 */
FLUID_SEQ_KEYPRESSURE, /**< Polyphonic aftertouch event @since 1.1.7 */
FLUID_SEQ_SYSTEMRESET, /**< System reset event @since 1.1.0 */ FLUID_SEQ_SYSTEMRESET, /**< System reset event @since 1.1.0 */
FLUID_SEQ_UNREGISTERING, /**< Called when a sequencer client is being unregistered. @since 1.1.0 */ FLUID_SEQ_UNREGISTERING, /**< Called when a sequencer client is being unregistered. @since 1.1.0 */
FLUID_SEQ_LASTEVENT /**< Defines the count of event enums @deprecated As of 1.1.7 this enum value is deprecated and will be removed in a future release, because it prevents adding new enum values without breaking ABI compatibility. */ FLUID_SEQ_LASTEVENT /**< Defines the count of event enums @deprecated As of 1.1.7 this enum value is deprecated and will be removed in a future release, because it prevents adding new enum values without breaking ABI compatibility. */
@ -103,6 +104,7 @@ FLUIDSYNTH_API void fluid_event_volume(fluid_event_t* evt, int channel, short va
FLUIDSYNTH_API void fluid_event_reverb_send(fluid_event_t* evt, int channel, short val); FLUIDSYNTH_API void fluid_event_reverb_send(fluid_event_t* evt, int channel, short val);
FLUIDSYNTH_API void fluid_event_chorus_send(fluid_event_t* evt, int channel, short val); FLUIDSYNTH_API void fluid_event_chorus_send(fluid_event_t* evt, int channel, short val);
FLUIDSYNTH_API void fluid_event_key_pressure(fluid_event_t* evt, int channel, short key, short val);
FLUIDSYNTH_API void fluid_event_channel_pressure(fluid_event_t* evt, int channel, short val); FLUIDSYNTH_API void fluid_event_channel_pressure(fluid_event_t* evt, int channel, short val);
FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t* evt); FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t* evt);

View file

@ -81,6 +81,7 @@ FLUIDSYNTH_API int fluid_synth_pitch_wheel_sens(fluid_synth_t* synth, int chan,
FLUIDSYNTH_API int fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval); FLUIDSYNTH_API int fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval);
FLUIDSYNTH_API int fluid_synth_program_change(fluid_synth_t* synth, int chan, int program); FLUIDSYNTH_API int fluid_synth_program_change(fluid_synth_t* synth, int chan, int program);
FLUIDSYNTH_API int fluid_synth_channel_pressure(fluid_synth_t* synth, int chan, int val); FLUIDSYNTH_API int fluid_synth_channel_pressure(fluid_synth_t* synth, int chan, int val);
FLUIDSYNTH_API int fluid_synth_key_pressure(fluid_synth_t* synth, int chan, int key, int val);
FLUIDSYNTH_API int fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank); FLUIDSYNTH_API int fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank);
FLUIDSYNTH_API int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id); FLUIDSYNTH_API int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id);
FLUIDSYNTH_API FLUIDSYNTH_API

View file

@ -237,6 +237,14 @@ fluid_seq_fluidsynth_callback(unsigned int time, fluid_event_t* evt, fluid_seque
} }
break; break;
case FLUID_SEQ_KEYPRESSURE:
{
fluid_synth_key_pressure(synth, fluid_event_get_channel(evt),
fluid_event_get_key(evt),
fluid_event_get_value(evt));
}
break;
case FLUID_SEQ_SYSTEMRESET: case FLUID_SEQ_SYSTEMRESET:
{ {
fluid_synth_system_reset(synth); fluid_synth_system_reset(synth);
@ -314,6 +322,11 @@ fluid_sequencer_add_midi_event_to_buffer(void* data, fluid_midi_event_t* event)
case CHANNEL_PRESSURE: case CHANNEL_PRESSURE:
fluid_event_channel_pressure(&evt, chan, fluid_midi_event_get_program(event)); fluid_event_channel_pressure(&evt, chan, fluid_midi_event_get_program(event));
break; break;
case KEY_PRESSURE:
fluid_event_key_pressure(&evt, chan,
fluid_midi_event_get_key(event),
fluid_midi_event_get_value(event));
break;
case MIDI_SYSTEM_RESET: case MIDI_SYSTEM_RESET:
fluid_event_system_reset(&evt); fluid_event_system_reset(&evt);
break; break;

View file

@ -101,7 +101,6 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off)
{ {
int i; int i;
chan->key_pressure = 0;
chan->channel_pressure = 0; chan->channel_pressure = 0;
chan->pitch_bend = 0x2000; /* Range is 0x4000, pitch bend wheel starts in centered position */ chan->pitch_bend = 0x2000; /* Range is 0x4000, pitch bend wheel starts in centered position */
@ -132,6 +131,11 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off)
} }
} }
/* Reset polyphonic key pressure on all voices */
for (i = 0; i < 128; i++) {
fluid_channel_set_key_pressure(chan, i, 0);
}
/* Set RPN controllers to NULL state */ /* Set RPN controllers to NULL state */
fluid_channel_set_cc (chan, RPN_LSB, 127); fluid_channel_set_cc (chan, RPN_LSB, 127);
fluid_channel_set_cc (chan, RPN_MSB, 127); fluid_channel_set_cc (chan, RPN_MSB, 127);

View file

@ -41,7 +41,7 @@ struct _fluid_channel_t
int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */ int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */
fluid_preset_t* preset; /**< Selected preset */ fluid_preset_t* preset; /**< Selected preset */
int key_pressure; /**< MIDI key pressure */ char key_pressure[128]; /**< MIDI polyphonic key pressure */
int channel_pressure; /**< MIDI channel pressure */ int channel_pressure; /**< MIDI channel pressure */
int pitch_bend; /**< Current pitch bend value */ int pitch_bend; /**< Current pitch bend value */
int pitch_wheel_sensitivity; /**< Current pitch wheel sensitivity */ int pitch_wheel_sensitivity; /**< Current pitch wheel sensitivity */
@ -106,10 +106,10 @@ int fluid_channel_get_interp_method(fluid_channel_t* chan);
((chan)->cc[num] = (val)) ((chan)->cc[num] = (val))
#define fluid_channel_get_cc(chan, num) \ #define fluid_channel_get_cc(chan, num) \
((chan)->cc[num]) ((chan)->cc[num])
#define fluid_channel_get_key_pressure(chan) \ #define fluid_channel_get_key_pressure(chan, key) \
((chan)->key_pressure) ((chan)->key_pressure[key])
#define fluid_channel_set_key_pressure(chan, val) \ #define fluid_channel_set_key_pressure(chan, key, val) \
((chan)->key_pressure = (val)) ((chan)->key_pressure[key] = (val))
#define fluid_channel_get_channel_pressure(chan) \ #define fluid_channel_get_channel_pressure(chan) \
((chan)->channel_pressure) ((chan)->channel_pressure)
#define fluid_channel_set_channel_pressure(chan, val) \ #define fluid_channel_set_channel_pressure(chan, val) \

View file

@ -432,6 +432,27 @@ fluid_event_channel_pressure(fluid_event_t* evt, int channel, short val)
evt->value = val; evt->value = val;
} }
/**
* Set a sequencer event to be a polyphonic aftertouch event.
* @param evt Sequencer event structure
* @param channel MIDI channel number
* @param key MIDI note number (0-127)
* @param val Aftertouch amount (0-127)
* @since 1.1.7
*/
void
fluid_event_key_pressure(fluid_event_t* evt, int channel, short key, short val)
{
evt->type = FLUID_SEQ_KEYPRESSURE;
evt->channel = channel;
if (key < 0) key = 0;
if (key > 127) key = 127;
if (val < 0) val = 0;
if (val > 127) val = 127;
evt->key = key;
evt->value = val;
}
/** /**
* Set a sequencer event to be a midi system reset event. * Set a sequencer event to be a midi system reset event.
* @param evt Sequencer event structure * @param evt Sequencer event structure

View file

@ -185,7 +185,7 @@ fluid_mod_get_source_value(const unsigned char mod_src,
val = fluid_voice_get_actual_key(voice); val = fluid_voice_get_actual_key(voice);
break; break;
case FLUID_MOD_KEYPRESSURE: case FLUID_MOD_KEYPRESSURE:
val = fluid_channel_get_key_pressure (chan); val = fluid_channel_get_key_pressure(chan, voice->key);
break; break;
case FLUID_MOD_CHANNELPRESSURE: case FLUID_MOD_CHANNELPRESSURE:
val = fluid_channel_get_channel_pressure (chan); val = fluid_channel_get_channel_pressure (chan);

View file

@ -58,6 +58,7 @@ static int fluid_synth_modulate_voices_LOCAL(fluid_synth_t* synth, int chan,
int is_cc, int ctrl); int is_cc, int ctrl);
static int fluid_synth_modulate_voices_all_LOCAL(fluid_synth_t* synth, int chan); static int fluid_synth_modulate_voices_all_LOCAL(fluid_synth_t* synth, int chan);
static int fluid_synth_update_channel_pressure_LOCAL(fluid_synth_t* synth, int channum); static int fluid_synth_update_channel_pressure_LOCAL(fluid_synth_t* synth, int channum);
static int fluid_synth_update_key_pressure_LOCAL(fluid_synth_t* synth, int chan, int key);
static int fluid_synth_update_pitch_bend_LOCAL(fluid_synth_t* synth, int chan); static int fluid_synth_update_pitch_bend_LOCAL(fluid_synth_t* synth, int chan);
static int fluid_synth_update_pitch_wheel_sens_LOCAL(fluid_synth_t* synth, int chan); static int fluid_synth_update_pitch_wheel_sens_LOCAL(fluid_synth_t* synth, int chan);
static int fluid_synth_set_preset (fluid_synth_t *synth, int chan, static int fluid_synth_set_preset (fluid_synth_t *synth, int chan,
@ -1724,6 +1725,52 @@ fluid_synth_update_channel_pressure_LOCAL(fluid_synth_t* synth, int chan)
return fluid_synth_modulate_voices_LOCAL (synth, chan, 0, FLUID_MOD_CHANNELPRESSURE); return fluid_synth_modulate_voices_LOCAL (synth, chan, 0, FLUID_MOD_CHANNELPRESSURE);
} }
/**
* Set the MIDI polyphonic key pressure controller value.
* @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param key MIDI key number (0-127)
* @param val MIDI key pressure value (0-127)
* @return FLUID_OK on success, FLUID_FAILED otherwise
*/
int
fluid_synth_key_pressure(fluid_synth_t* synth, int chan, int key, int val)
{
int result;
fluid_return_val_if_fail (key >= 0 && key <= 127, FLUID_FAILED);
fluid_return_val_if_fail (val >= 0 && val <= 127, FLUID_FAILED);
FLUID_API_ENTRY_CHAN(FLUID_FAILED);
if (synth->verbose)
FLUID_LOG(FLUID_INFO, "keypressure\t%d\t%d\t%d", chan, key, val);
fluid_channel_set_key_pressure (synth->channel[chan], key, val);
result = fluid_synth_update_key_pressure_LOCAL (synth, chan, key);
FLUID_API_RETURN(result);
}
/* Updates key pressure from within synthesis thread */
static int
fluid_synth_update_key_pressure_LOCAL(fluid_synth_t* synth, int chan, int key)
{
fluid_voice_t* voice;
int i;
int result = FLUID_OK;
for (i = 0; i < synth->polyphony; i++) {
voice = synth->voice[i];
if (voice->chan == chan && voice->key == key) {
result = fluid_voice_modulate(voice, 0, FLUID_MOD_KEYPRESSURE);
if (result != FLUID_OK)
return result;
}
}
return result;
}
/** /**
* Set the MIDI pitch bend controller value on a MIDI channel. * Set the MIDI pitch bend controller value on a MIDI channel.
* @param synth FluidSynth instance * @param synth FluidSynth instance
@ -4967,6 +5014,11 @@ fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event)
case CHANNEL_PRESSURE: case CHANNEL_PRESSURE:
return fluid_synth_channel_pressure(synth, chan, fluid_midi_event_get_program(event)); return fluid_synth_channel_pressure(synth, chan, fluid_midi_event_get_program(event));
case KEY_PRESSURE:
return fluid_synth_key_pressure(synth, chan,
fluid_midi_event_get_key(event),
fluid_midi_event_get_value(event));
case PITCH_BEND: case PITCH_BEND:
return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event)); return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event));