Re-writing C++ bit manipulation function in Python

118 Views Asked by At

I'm attempting to convert some C++ code that I found online that is used for reordering a bitmap to be used with a specific OLED display for a MIDI controller - Akai Fire. The display uses a strange configuration to display the bits as pixels, as is documented in the blog I've shared at the bottom of the page.

The aim is to be able to display text on the screen. The messages are sent as MIDI SysEx using 7 bits per byte for the pixels, reserving the MSB for a 0 as is standard with MIDI data bytes. I've had a reasonable amount of success in that I've managed to get the correct set of pixels to turn on, there just mangled up so it's undreadable. I believe the error is in the bit manipulation function that I have attempted to translate to Python.

Here is the original code.

static void _FIRE_PlotPixel(unsigned X, unsigned Y, unsigned C) {
  unsigned RemapBit;
  //
  if (X < 128 && Y < 64) {
    //
    // Unwind 128x64 arrangement into a 1024x8 arrangement of pixels.
    //
    X += 128 * (Y/8);
    Y %= 8;
    //
    // Remap by tiling 7x8 block of translated pixels.
    //
    RemapBit = _aBitMutate[Y][X % 7];
    if (C > 0) {
      _aOLEDBitmap[4 + X/7*8 + RemapBit/7] |= 1u << (RemapBit % 7);
    } else {
      _aOLEDBitmap[4 + X/7*8 + RemapBit/7] &= ~(1u << (RemapBit % 7));
    }
  }
}

I'm first having to create a large list of 0's to set the values, which may be causing issues. Note I'm using 1178 as the size, and I was expecting to be 1175, but this isn't large enough so maybe there are some stray bytes in my bitmap, I'm not sure - Altough it does contain 1024 bytes, which is correct for 1-bit per pixel on 128x6

TestBitMap = [0x00 for i in range(1178)]

Then creating the function to plot the pixels:

def PlotPixel(x, y, c):
    if x < 128 and y < 64:

        x += 128 * (y / 8)
        y %= 8

        RemapBit = BitMutate[int(y)][int(x % 7)]
        if c > 0:
            TestBitMap[4 + int(x / 7 * 8) + int(RemapBit / 7)] |= 1 << (int(RemapBit % 7))
        else:
            TestBitMap[4 + int(x / 7 * 8) + int(RemapBit / 7)] &= ~(1 << (int(RemapBit % 7)))

Then I'm calling it like this, where bits is my standard bitmap, generated with PIL with 1-bit per pixel (This works, I'm able to see the image correctly when I extract the bits from the standard bitmap):

for x in range(128):
    for y in range(64):
        # Plot the pixels - essentially sets all bits to 0x00, ie black
        PlotPixel(x, y, 0)

for y in range(64):
    for x in range(128):
        if bits[(55 - y) * int(128 / 8) + int(x / 8)] & (0x80 >> (x % 8)):
            PlotPixel(x + 4, y + 4, 1)

return TestBitMap

The bits are being rearranged using this List, which was documented by the original person blogging about this problem:

BitMutate = [[13, 19, 25, 31, 37, 43, 49],
             [0, 20, 26, 32, 38, 44, 50],
             [1, 7, 27, 33, 39, 45, 51],
             [2, 8, 14, 34, 40, 46, 52],
             [3, 9, 15, 21, 41, 47, 53],
             [4, 10, 16, 22, 28, 48, 54],
             [5, 11, 17, 23, 29, 35, 55],
             [6, 12, 18, 24, 30, 36, 42]]

Here is a link to the blog that I have been using as research: https://blog.segger.com/decoding-the-akai-fire-part-3/

I'm using the bitmap and the expected SysEx message output they provide to test and compare to see how my version is responding.

I know Python probably isn't the best Language for this problem, but this is what I'm familiar with and because of the end use it's most suitable. I'm using this project to learn more about C/C++. I feel like I'm really close just obviously missing something crucial. Any help would be greatly appreciated :)

0

There are 0 best solutions below