Bit Manipulation LSB/MSB

Hi guys, i'm working with MIDI sysex where each byte only uses 7 bits so every byte can be a maxium decimal of 127, whenever a value must be 8bits or more you gotta use LSB/MSB and so on.

I've been trying to wrap my head around it, i've been mainly a web programmer so i never really had to deal with bit manipulation.

First, I get 2 bytes that make up an int in the range of 0 to 511, 0 would be 0x00,0x00 and 511 would be 0x03,0x7F then i need to convert this into the int, i do it like this

msb = 0x03
lsb = 0x7F
integer = (msb*128)+lsb

that works great, but now i need to go the other way around and take a number like 284 and convert it into two 7bit bytes.

so i wrote code that converts an the int to bytes but my code is based on "if" statements and i'm sure there's better code using bit manipulation to do it (code below is not my actual code, i just wrote this for the example, i don't have my files with me)

max = 127;
Pn = 284;
If (Pn <= max){
    B1 = 00;
    B2 = Pn;
} else if (Pn>max&&Pn<=(max*2)){
    B1 = 01;
    B2 = Pn-max;
} else if (Pn>(max*2)&&Pn<=(max*3)){
    B1 = 02;
    B2 = Pn-(max*2);
} else {
    B1 = 03;
    B2 = Pn-(max*3);
}

I'm trying to learn and wrap my head around this because i then have to figure out how to use other values, in particular this one that is 3 bytes (7bits each)

Byte1 - bits 6-0
Byte2 - bits 13-7
Byte3 - bits 15-14

and then i have to conver those to an int and then an int back to those 3 bytes!

thanks fo your help in advance!

You could use a struct with bitfields, combined with a union, to do the conversion automatically. No math required.

jremington:
You could use a struct with bitfields, combined with a union, to do the conversion automatically. No math required.
C Bit Fields | Microsoft Learn
c - Converting Bit Field to int - Stack Overflow

I took your links.The first one sex:

"the ordering of the bitfields within a struct is implementation-dependent"

Is this not the case in Ardu.ino? Is it certainly defined and therefor exploitable in this fashion?

If you can't rely on an order, engineering a struct to work leaves you vulnerable to a change in implementation. I am sure that has bitten someone, somewhere at some time.

The Microsoft link has the certainty, but only within the "Microsoft specific" section. I still wouldn't use it as it locks you into Microsoft's idea, and makes you trust them…

The long way around may be tedious but it wouldn't be slow and it would be clear and it would be portable.

-- a7

You can't even rely on the order of bytes within an integer! The C/C++ language IS implementation dependent.

what you have here, really, is a need to deal with an int OR an array of at most three bytes.
here ONE approach to it. I chose not to use explicity unsigned objects but I guess you could do so.

int packed
byte unpacked[3];

int pack( byte * pBytes)
{ return pbytes + 0x80 * ((pbytes+1) + 0x4000*( *(pBytes+2));

void unpack( int packed, byte * unpacked)
{
*unpacked = packed & 0x7f;
*(unpacked+1) = packed >> 7 & 0x7f;
*(unpacked+2) = packed >> 14 & 03;

}

now i need to go the other way around and take a number like 284 and convert it into two 7bit bytes.

// Assuming int n < 16384 (14 bits)
n_LSB = n & 127;
n_MSB = n >> 7;

I wouldn't count on structure bitfields/unions to do this correctly; they're not "required" to pack bits, and the compiler is "somewhat likely" (and definitely "is allowed to") put two 7bit fields each in its own 8bit byte.