I am making a midi musical instrument using an arduino controlling a Wav-Trigger SD card sample player
I wish to add vibrato using a FSR.
I am trying to achieve this by adding Vibrato MSB and LSB to the existing,
// Send a MIDI note-on message. ( Like so)
pitch_bend(channel, bendLSB, bendMSB, SerialChannels );
This is example rough idea code I am trying below;
//Read the vibrato pin - If it's changed significantly change bend value MSB and LSB
vibratoVal = analogRead(VibratoPin); // read FSR
if ( vibratoVal < MIN_PRESSURE){
int PitchBend= 8192; // No bend
} else
{
int PitchBend = map( vibratoVal, MIN_PRESSURE, MAX_PRESSURE, ,8192, 9640);//use the min 600 -max 680 pressure range I measured from FSR
PitchBend = constrain (PitchBend ,8192, 9640); // for (aprox)+1 semitone
My questions are the decimal numbers for pitch bend I use in the mapping equation for a one semitone bend correct ,( for max possible bend range+ 5 semitones) , is the basic sketch on the right track and more important I wish to convert the PitchBend to MSB and LSB to pass to a MIDI note-on message, how do I do this?
For converting my decimal PitchBend values to Binary LSB ,MSB is this the way;
byte lowValue = PitchBend & 0x7F; byte highValue = PitchBend >> 7; ?
Can someone please help with the code to achieve my aims?
I'm not a MIDI expert...
According to this page (http://sites.uci.edu/camp2014/2014/04/30/managing-midi-pitchbend-messages/) the amount of pitch bend you get with a particular integer value depends on the instrument/device.
Do you know what the real MIN_PRESSURE & MAX_PRESSURE readings you're getting with your FSR? If not, you'll need to write a little test program to find out.
Of course for vibrato, you'll need to pitch-shift positive & negative.
To get MSB & LSB, look-up bit masking & bit shifting. i.e. If you mask (block-out) the 8 MSBs from a 16-bit integer you're left with the 8 LSBs, and you can convert it to a byte (8-bits). And, if you right-shift 8-bits, the 8-MSBs are shifted into the 8-LSB locations with zeros shifted into the MSB positions and you can then convert/read the 8-MSBs as a byte.
...Bit manipulation may be confusing if you are not used to working with binary (or hexadecimal) numbers, because it doesn't make sense with decimal numbers... But, when you see a regular decimal integer, remember it's really binary inside the computer (or inside the Arduino).
Many thanks for your prompt reply.
Funny thing was I was reading the "Managing MIDI pitchbend messages" page you quoted and editing my post for the amount of pitch bend you get with a particular integer value depends on the instrument/device, as you posted your reply.
I have added the bend values on my post for a bend of 1 semitone, (on a max possable bend of 5 semitones on the instrument).
Yes I do know what the real MIN_PRESSURE & MAX_PRESSURE readings I am getting with my FSR.
I have called it vibrato, but for my needs I should really call it Bebung (see Bebung - Wikipedia)
as I only wish to bend upwards.
While the actual pitch bend is specified as a 14 bit number in MIDI, you can also specify the pitch bend sensitivity by writing to the MIDI controllers like this:-
// set up Pitch bend sensitivity
controlSend(101, 0);
controlSend(100, 0);
controlSend(6,72); // set to 6 octaves
controlSend(38, 0); // and zero cents
This sets it up to give a 6 octave range.
See the control messages here https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 (https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2)
Thank you Mike,
I can sort of see what you are saying, but I still do not fully understand the process to convert my analogue voltage readings from the FSR to a one semitone midi Pitch bend message.
Am I on the right track with my basic sketch and am I right that I can convert my decimal PitchBend value to Binary LSB, MSB is this the way;
byte low Value = PitchBend & 0x7F; byte high Value = PitchBend >> 7; ?
Sorry for any confusion as to my purpose of using LSB and MSB, I will now explain why I wish to use this. On my instrument I already have a +-5 semitone buttons for changing the pitch of the whole instrument. This uses an array of LSB, MSB values,
I wont to add the FSR vibrato value to the existing Pitchbend message.
byte low Value = PitchBend & 0x7F; byte high Value = PitchBend >> 7; ?
Yes this is right but remember that anything from the A/D converter you get with analogRead is going to be a 10 bit number. That is 0 to 1023, and not the 14 bit number that the pitch bend will take.
As can be seen from my initial question, I am mapping my min and max pressure FSR readings to the selected pitchbend range as a proportion of pitchbend 0 to 16384. I am presuming this gives the 14 bit number that the pitch bend will take.
As I will be adding this to an existing pitch bend of +-5 semitone, using buttons for changing the pitch of the whole instrument, I am mapping:
pitchbendVal = map( vibratoVal, MIN_PRESSURE, MAX_PRESSURE, , 0, 1448);
for a max` bend of approximately + one semitone (Bebung) .
I am presuming this gives the 14 bit number that the pitch bend will take.
Yes.
I think you are on the right track.