Skip to content

Add support for NoteOff-triggered modulators #1605

@derselbst

Description

@derselbst

Related discussion

#1598

Is your feature request related to a problem?

The original use-case is explained in this comment. The problem is, that e.g. a flute sounds indefinitely while the sustain pedal is depressed after a noteOff has been received.

Describe the solution you'd like

A new modulator source Note-Off Velocity is to be introduced (with it's value yet to be defined).

As the name says, it's input value evaluates to the velocity of the noteOff event, ranging from [0;127]. The MIDI spec says that a noteOff velocity=64 should be used as "default" or "ignored" value.

The input value will then be mapped by the well-known (switch, linear, convex, concacve) mappings into [-1;1] range as usual.

Iff the noteOff event has not been received by the synth, the mapped input value of this source is considered zero, effectively causing the entire modulator to be disabled, as its effect evaluates to zero.

If a noteOn event with velocity=0 is sent, it shall be interpreted as noteOff velocity=64 as per MIDI spec.

A noteOff event with velocity=0 shall not receive a special treatment! Instead, the user defined mappings should provide the desired mapping.

Describe alternatives you've considered

Original and superseded proposal:

To address this problem, the user requires a modulator, that gets only activated after a noteOff event has been received. This would allow to manipulate the volEnvSustain or even adding further effects after receiving a noteOff event.

My preferred solution is to introduce a new modulator transformation. This new transform should evaluate to:

  • either 1, when a noteOff event has been received, or
  • 0 otherwise.

(Note that the behavior would be undefined for overlapping MIDI notes.)

Originally, the soundfont spec only supports two transforms: linear and absolute. A new transform - let's call it HasNoteOff - can be added, which is meant to be bit-wise ORed with the other two transforms.

The result of this binary transform (= 0 or 1) would then be multiplied with the modulator amount right before it's being added to its destination generator.

The sfModTransOper field in the Soundfont is two bytes in length, so we have plenty of bits to spare. I'm suggesting to define HasNoteOff = 0x8000 ie. setting the highest bit.

The spec also states that "Unknown or undefined values are ignored." which makes this solution backward compatible to existing implementations. In fact, fluidsynth actively disables modulators that use transforms it doesn't know about.

Additional context

Fluidsynth currently does not support or handle noteOff velocity. I.e. all API functions need to be duplicated (e.g. fluid_synth_noteoff2()) and shell commands need to receive the velocity as additional parameter.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions