How do I apply aftertouch volume in combination with velocity?

As soon as the key is played it starts receiving aftertouch values, but I have no idea how to integrate them since the volume of the note is already determined by the velocity, and this is the initial velocity that should be considered

after doing some tests I thought that it would be best if it was relative to the initial velocity with negative values (AT/127 - 0.5) but I’m not sure what I’m doing.

Gains are combined by multiplication. finalGain = initialGainFromVelocity * aftertouchGain.

1 Like

If I do that with the midi value (from 0 to 127) I will get excessively high values, if I do it with the normalized value between 0 and 1 I will get very low values. Also, this would never subsequently generate a level higher than the initial value, I still don’t understand it.

There really isn’t anything to understand here, but obviously you wouldn’t use the midi value directly, but work with normalised gain factors.
Just map the value range to whatever works well and feels appropriate for what you’re building. It’s not uncommon to provide the user with some means to configure modulation amounts. For aftertouch in particular, a skewed transfer curve might make sense too, because different keyboards behave wildly different when it comes to translating physical force to aftertouch.

If you just want to add an emphasis to gain (slightly increasing volume the harder you press the key), map it to 1…2 (with the factor 2 being approx. +6 dB).

I want to add emphasis, but then I think the tremolo effect (moving the finger sideways) is probably caused by releasing pressure, so if it doesn’t take into account the volume reduction it might not work well.

So it should subtract, and if it subtracts, does it mean that the aftertouch should work as a velocity relative to the initial velocity?

I’m not looking for anything specific, I just want it to work like an aftertouch effect is expected to work, so I was looking for some standard method that works well with the initial value, whether it’s for volume, brightness, or whatever.

I haven’t found anything on the internet, and this thread didn’t get many replies, I thought this was more usual. hardly anyone uses this?

If by “subtract” you mean “attenuate”, e.g. making the synthesizer quieter the more pressure you apply, map the aftertouch value to 1…0.5 and multiply output gain with that. There is no standard that’s specifying how exactly it’s supposed to behave, aftertouch is just a regular midi CC (like modulation, expression, brightness, etc.) that you can use to modulate aspects of your sound in any way you want.
It has nothing to do with velocity.

Just try it out, or take a look at how other synthesizers utilize it, if you want to gain a better understanding about how it’s commonly used. For example, opening up the cutoff of a lowpass filter is pretty common when it comes to subtractive synthesis.

what I mean by subtract is that if after pressing the key I exert less pressure, the initial velocity should be subtracted

The synth I have in mind is the CS-80, in which “normal” velocity is related to aftertouch. Which calls it Touch Response.

I think it doesn’t matter if it is used as volume, filter, tone, or whatever, the problem is that it looks like two values are used together, the initial one and the after one. And I don’t know how to combine them.

The answer still is plain and simply “to combine gains, you multiply them”. Maybe I’m just not getting what exactly it is what confuses you. Anyway, to get into more detail, in the hope that it helps:

With MIDI, aftertouch behaves like any other controller (for channel aftertouch, that is). It is not guaranteed that you will receive any aftertouch value at all, and aftertouch CC updates can be received at any time, completely independent of whether a note is playing or not. CCs are not coupled with note on events, so you need to keep track of the current/last received aftertouch CC value internally. It is also safe to assume the value to be zero before you receive any update.

Velocity you will get along with the note on event. It will not change while the note is playing.
To combine both for gain adjustment, the answer still is: Map aftertouch CC to a gain range, and continuously multiply it with any other gain factors you’re using in your voice mixing. You should also smooth the controller value to avoid clicks due to sudden value jumps.
Example combination formula, for gain:
finalGain = baseGain * velocityGain * amplitudeADSRGain * smoothedAftertouchGain.
voiceOutput = oscillatorOutput * finalGain;

It does play a role what kinds of units you work with. Gains are multiplied, but for filter cutoff you’d probably add, and calculations on pitch or time may need other kinds of calculations.

If you insist on actually adding or subtracting, you can convert your gains to decibel, work with addition/subtraction in that representation, and then convert back to gain for applying it. I can’t see any good argument for doing so, though.

CS80: from the sketch I’d assume that “initial” describes the base values of brilliance and level on top of which aftertouch is being applied. Also, the CS80 uses polyphonic aftertouch, which is a little more involved than channel aftertouch. MIDI controllers that support it are rare. But I don’t think that this is your problem?

I have verified that after about 100ms the first aftertouch is received and has a value equal to the velocity. So I can’t multiply velocity and aftertouch because initially they are similar values and that would be like squaring.

I’ve tried the mean of the two values and it seems to work reasonably well for volume.

here is another way, from the top of my head here…
It is differential, which might be waht you are looking for.
use the noteon velocity as the normal, I call it scaled touch here:
scaledTouch = (aftertouch/note_onvelocity)
So this gives a signal that has a consistent envelop, no matter how quiet you play.

Now you can mix the scaled touch with the normal velocity and aftertouch velo, to get a nice blend.
sense=0…1, output in 0…127 range
(sense* scaledTouch) * 127. + (1-sense)* aftertouch

There are all sort of other schemes too, it just depends on what expression you want to give the player.

1 Like

this works well, especially since it is possible to adjust the sensitivity

I assume that you made a mistake in the last term of the formula, and that it is the velocity that must be multiplied, not aftertouch

Yes, I ommited the following stuff, I’ll specify:
At noteon, the aftertouch is assumed to be equal to the noteon velocity (since there is no aftertouch info yet…).
Since we dont have aftertouch yet, indeed we must use the velocity itself at that point.

at noteon event:
aftertouchReceived=false;
at aftertouch event;
aftertouchReceived=true;

allways:

perceivedAftertouch = aftertouchReceived ? aftertouch : noteonvelocity;
scaledTouch = (perceivedAftertouch/note_onvelocity);
myTouch = (sense* scaledTouch) * 127. + (1-sense)* perceivedAftertouch;

Do not assume that the first aftertouch event will have the same ‘velocity’ value as the corresponding note on event. This is my experience with Arturia Beatstep aftertouch. I would use that first AT event value as the neutral position of the modulation so there will be no sudden jumps with modulation.

I’ve done tests and I’m not sure if it’s the ideal, in any case I don’t get the meaning of scaledTouch multiplied by sense. It seems that a simple blend of aftertouch with velocity, balanced with sense, works fine.

float myTouch = (sense * afterTouch) + (1.0f-sense) * velocity;