Hi All,
I am a midi newbie and would be very grateful for your help with understanding how Midi handles volume variables.
I am building a digital accordion MIDI controller, and have the following requirements for volume control.
1) A bellows air pressure sensor shall be able to control the entire range of expression from nothing (when the bellows are not moving) to pianissimo when the bellows are moved very gently, to fortissimo (max air pressure in the sensor).
2) Ability to attenuate individual channels, to facilitate balance adjustment between left hand side and right hand side (RHS and LHS are on different channels).
3) Master control knob to be able to tweak master volume directly from the midi controller, rather than the separate processor unit.
4) I do not have the key stroke velocity implemented, so the velocity for each note in note-On-Off message shall be a constant.
I feel like I am drowning in the jacuzzi of MIDI commands, but after reading the documentation, I came up with the following:
1) Assign expression (cc11) to the bellows sensor, allowing values from 0 to 127 depending on the sensor reading;
2) Assign volume (cc7) to a rotary encoder that attenuates either LHS channel or RHS channel, depending on the knob rotation direction. Set Volume as 127 for both channels to begin with, and reduce it for one of the channels by the amount read from the encoder.
3) I am aware that there is a MIDI Master Volume Universal SysEx message that sets volume for all channels, but I cannot find how this variable is used in conjunction with the others (cc7 and cc11). Is this the equivalent of turning the gain knob on the midi processor? Or is the processor volume control completely separate from the MIDI Master Volume Universal SysEx message on the controller?
4) As the velocity is constant, shall I just use default 127 for note On, and 0 for note Off?
The potential problem seems to be in how cc7 and cc11 interact with each other:
Per the Midi documentation, the following formula is used to determine the gain:
Gain in dB = (40 * log10(cc7/127)) + (40 * log10(cc11/127))
Reading the formula, it appears to me that even if I have expression set at 0 (no bellows movement), the controller will still play the notes, because volume is >0. Is my understanding correct? In this case I guess I'm back to the drawing board with assigning midi commands to various volume controls.
Thank you very much.
[quotePost id=18238]Gain in dB = (40 * log10(cc7/127)) + (40 * log10(cc11/127))
Reading the formula, it appears to me that even if I have expression set at 0 (no bellows movement), the controller will still play the notes, because volume is >0. Is my understanding correct?[/quotePost]
Be aware that the output of the formula is gain in decibels, with a range of −∞ (silence) to 0 (maximum). log₁₀(0) is normally undefined, but is treated as −∞ in this formula. If one or both sides of the addition is −∞ then the output of the entire formula is also −∞.
Here are two places that the volume-and-expression formula appears:
General MIDI 2 Specification, PDF page 12 (printed page 8):
Gain in dB = (40 * log₁₀(cc7/127)) + (40 * log₁₀(cc11/127))
General MIDI Level 1 Developer Guidelines PDF page 13 (printed page 9):
L(dB) = 40 log (V/127²) where V = (volume × expression)
Ignoring the differences in variable names, these versions of the formula are mathematically equivalent because of the property log(a) + log(b) = log(ab). More specifically, I'll use the following variable names:
G is the gain in decibels from −∞ (silence) to 0 (maximum).
V is the MIDI volume value from 0 to 127.
E is the MIDI expression value from 0 to 127.
Starting with
G = (40 × log₁₀(V/127)) + (40 × log₁₀(E/127))
then factoring out the 40 from both sides of the addition
G = 40 × ( log₁₀(V/127) + log₁₀(E/127) )
then using the property log(a) + log(b) = log(ab) gets
G = 40 × log₁₀( (V/127) × (E/127) )
I find this version of the formula easier to understand that if one or both of the velocity V or expression E is 0, then the result will be silence.
[quotePost id=18238]As the velocity is constant, shall I just use default 127 for note On, and 0 for note Off?[/quotePost]
My understanding is that Note On velocity value mainly controls volume, but can also add other effects. On some MIDI devices, when the Note On velocity is 127 or otherwise very large, the resulting instrument sound might sound harsher or have some other exaggerated emphasis. If you use a constant Note On velocity of 127, you might always hear the harsher version of the instrument sound.
So if you want to be able to use various MIDI devices to generate the instrument sound, you may want to avoid a constant Note On velocity of 127, in case it causes an unwanted change in the instrument sound. When I make MIDI files, I usually use a Note On velocity of 100 as a default value.
On the other hand, if you know you are only going to use a specific MIDI device to make the instrument sound, you can test if Note On velocity 127 sounds okay to you and decide to use that if you want.
By the way, my understanding is the Note On velocity will combine the same way into the formula...
Y is the Note On velocity from 1 to 127
G = (40 × log₁₀(V/127)) + (40 × log₁₀(E/127)) + (40 × log₁₀(Y/127))
or
G = 40 × log₁₀( (V/127) × (E/127) × (Y/127) )
My understanding is Note Off velocity is rarely used by MIDI devices for anything. When I make MIDI files, I usually end notes with a Note On with velocity 0, or sometimes with a Note Off with velocity 0.
[quotePost id=18238]I am aware that there is a MIDI Master Volume Universal SysEx message that sets volume for all channels, but I cannot find how this variable is used in conjunction with the others (cc7 and cc11).[/quotePost]
I believe the MIDI Master Volume value would combine in the same way...
M is the MIDI Master Volume value from 0 to 16383
G = (40 × log₁₀(M/16383)) + (40 × log₁₀(V/127)) + (40 × log₁₀(E/127)) + (40 × log₁₀(Y/127))
or
G = 40 × log₁₀( (M/16383) × (V/127) × (E/127) × (Y/127) )
...but I don't use the MIDI Master Volume System Exclusive message when I make MIDI files, so I have no experience with how consistently it behaves on various MIDI devices.
You can think of volume as the "maximum playable volume" and expression as "the current percentage of the maximum playable volume". Not an exact formula, as I am making this up off the cuff, but in the broadest sense
playback volume = expression percent * channel volume
(Bavi posted a way more specific formula breakdown while I was typing 😛 )
Both volume and expression can have values from 0 - 127.
So, say, just for nice easy numbers, you have set your volume (cc 7) to 100. You can then use expression (cc 11) to play any volume up to a maximum of 100. Since expression runs from 0 - 127, and expression of (0/127) * 100 = 0, and thus no sound. Expression of (127/127) * 100 = 100, thus you have sound at your maximum set volume.
If you then change your volume to 127, but do not modify your expression, you now have (127/127) * 127 = 127, so now you will be playing at absolute full volume.
Many files I have seen have expression fixed at 127, so the only command affecting the perceived volume is the volume command, and vice versa where volume is fixed and expression is doing all of the adjustments.
All of the files in the project I am working on make extensive use of both volume and expression for controlling playback levels.
I haven't used master volume before, so unfortunately I am not sure how that behaves.
However, based on my experience, it sounds to me like 1) and 2) from your question are a correct way to go about that. I'll leave the rest of the mathematics to Bavi 😉
Thank you very much. This clears up a few things.
...log(a) + log(b) = log(ab)... It's been so many years since I've seen that in a textbook that I have completely forgot about this one.:D
Re velocity at 127 - thank you, I was aware of velocity being able to affect timbre of some instruments and I am not aware of any single accordion processor that makes use of this feature, but if I was to select a different instrument, I might run into trouble. I will fix it at 100 then, as per your advice.
Also thanks for confirming NoteOn 0 - that's how I have it coded currently.
I would like to correct my previous post - at least the Ilya Efimov's accordion files use velocity to determine the attack. There might be others, albeit it is highly unusual for squeezeboxes.