Birch-san / juicysfplugin

Audio plugin (e.g. VST, AU) to play soundfonts on macOS, Windows, Linux
GNU General Public License v3.0
233 stars 29 forks source link

[Suggestion] Lower value for release #34

Open switchgeer opened 2 years ago

switchgeer commented 2 years ago

Something that would be nice to have in here would be the 'zero value' for note release being set lower. Most instruments I use have a natural tail, which sounds nice in most cases, however being able to cut the note as soon as it stops with no release would be nice.

Birch-san commented 2 years ago

it may already be possible to do this by sending the right MIDI message. I pass every MIDI message to fluidsynth, and it implements them according to the Soundfont Specification.

Chapter 9.2:
MIDI CC120 All Sound Off - When received with any data value, all notes playing in the key-on state bypass the release phase and are shut off, regardless of the sustain or sostenuto positions.

Maybe you could send a MIDI CC120 after every "note off"?

otherwise, I think what you really want is to set releaseModEnv or releaseVolEnv to a negative value:

8.1.2 Generator Enumerators Defined
30 releaseModEnv This is the time, in absolute timecents, for a 100% change in the Modulation Envelope value during release phase. For the Modulation Envelope, the release phase linearly ramps toward zero from the current level. If the current level were full scale, the Modulation Envelope Release Time would be the time spent in release phase until zero value were reached. A value of 0 indicates a 1 second decay time for a release from full level. A negative value indicates a time less than one second; a positive value a time longer than one second. For example, a release time of 10 msec would be 1200log2(.01) = -7973.

38 releaseVolEnv This is the time, in absolute timecents, for a 100% change in the Volume Envelope value during release phase. For the Volume Envelope, the release phase linearly ramps toward zero from the current level, causing a constant dB change for each time unit. If the current level were full scale, the Volume Envelope Release Time would be the time spent in release phase until 100dB attenuation were reached. A value of 0 indicates a 1-second decay time for a release from full level. A negative value indicates a time less than one second; a positive value a time longer than one second. For example, a release time of 10 msec would be 1200log2(.01) = -7973.
See also 8.1.3 Generator Summary

modulators (i.e. mapping of MIDI CCs to generators) are defined like this:
https://github.com/Birch-san/juicysfplugin/blob/master/Source/FluidSynthModel.cpp#L116-L126

looks like I already map MIDI CC 72 Release time to GEN_VOLENVRELEASE (a.k.a releaseVolEnv).

I think the problem for your use-case is that it's set to unipolar:
https://github.com/Birch-san/juicysfplugin/blob/master/Source/FluidSynthModel.cpp#L120

this means it maps 0 to 127 as "0 to 127 timecents" (1 second to lots of seconds) if set to bipolar: it'd map 0 to 127 as "-127 to 127 timecents" (0 seconds to lots of seconds). or something like that.
so, less range to play with, but becomes capable of going down to 0 secs.

I can't remember what's the difference between the modulation envelope and the volume envelope. nor do I really remember how to use the modulator API and interpret the soundfont specification.

that's the general area in which the change would need to be made. not sure about: