Converting 8-bit and 7-bit values in Python 3.x

1

I'm trying to convert unsigned integer values to ones represented as 4 7-bit bytes; the goal is to send data using Roland's address-mapped MIDI System Exclusive protocol, which represents address and size values like so:

MSB                                    LSB
---------    ---------    ---------    ---------
0aaa aaaa    0bbb bbbb    0ccc cccc    0ddd dddd

I unfortunately don't really know where to begin doing this; the goal is to do this in Python 3.x, which I'm prototyping in at the moment. What I'm really having trouble with is the math and bit manipulations, but oddly I can't really even find any general algorithms or rules of thumb for doing this. The closest I found was this discussion on solutions in Perl from around a decade ago, but I'm having a bit of trouble deciphering the Perl too. Other than that, I've only seen a couple C++ questions with answers recommending using bitsets.

For a specific usage example, say I want to send 128 bytes of data. This requires me to send a 4-byte size value using only the lower 7 bits of each byte. However, this value would normally be 0x00000080, where the upper bit in the LSB is 1, requiring conversion.

Sorry if this is confusing, and I may be way off base here, but can anyone point me in the right direction? I'm sure someone has done this before, since it seems like it would come up regularly in MIDI programming.

python
python-3.x
midi
asked on Stack Overflow Dec 31, 2020 by Lauren Croney

1 Answer

0

Variable-length quantities (as in the linked question) use a different encoding.

Anyway, to split a value into 7-bit bytes, extract the lowest 7 bits in each step, and then shift the remaining value right by 7 bits so that the next portion is in the right position in the next step:

def encode_as_4x7(value):
    result = []
    for i in range(4):
        result = [value & 0x7f] + result
        value >>= 7
    return result
answered on Stack Overflow Jan 1, 2021 by CL.

User contributions licensed under CC BY-SA 3.0