Переписать функцию манипуляции битами C ++ в Python - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь преобразовать некоторый код C ++, который я нашел в Интернете, который используется для переупорядочивания растрового изображения, которое будет использоваться с указанным c OLED-дисплеем для контроллера MIDI - Akai Fire. Дисплей использует странную конфигурацию для отображения битов в виде пикселей, что задокументировано в блоге, которым я поделился в нижней части страницы.

Цель состоит в том, чтобы иметь возможность отображать текст на экране. Сообщения отправляются как MIDI SysEx, используя 7 бит на байт для пикселей, резервируя MSB для 0, как это стандартно для байтов данных MIDI. У меня был достаточный успех в том, что мне удалось получить правильный набор пикселей для включения, он просто искажен, поэтому его невозможно прочитать. Я считаю, что ошибка в функции манипуляции битами, которую я пытался перевести на Python.

Вот исходный код.

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));
    }
  }
}

Сначала мне нужно создать большой список 0 для установки значений, которые могут вызывать проблемы. Обратите внимание, что я использую 1178 в качестве размера, и я ожидал, что будет 1175, но этого недостаточно, поэтому, возможно, в моем растровом изображении есть несколько случайных байтов, я не уверен - хотя он действительно содержит 1024 байта, что правильно для 1-битного на пиксель для 128x6

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

Затем создаем функцию для построения пикселей:

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)))

Затем я называю это так, где биты мои стандартное растровое изображение, сгенерированное с помощью PIL с 1 битом на пиксель (это работает, я могу правильно видеть изображение, когда извлекаю биты из стандартного растрового изображения):

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

Биты переставляются используя этот список, который был задокументирован оригинальным человеком, который ведет блог об этой проблеме:

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]]

Вот ссылка на блог, который я использовал в качестве исследования: https://blog.segger.com/decoding-the-akai-fire-part-3/

Я использую растровое изображение и ожидаемый вывод сообщений SysEx, которые они предоставляют для тестирования и сравнения, чтобы увидеть, как отвечает моя версия.

Я знаю, Python, вероятно, не лучший язык для это проблема, но это с чем я знаком и из-за конечного использования он наиболее подходит. Я использую этот проект, чтобы узнать больше о C / C ++. Я чувствую, что я действительно близко, просто явно упускаю что-то важное. Любая помощь будет принята с благодарностью :)

...