Работа с битовыми потоками в C - PullRequest
1 голос
/ 21 июня 2011

Я пишу некоторый код обработки сигнала в C, который имеет канал связи. На выходе я получаю кучу битов по мере их поступления.

for (n=0; n<BUFFER_LENGTH; n++) {
    /* do some processing that calculates x */
    output[n] = x > 0;
}

Вот мои вопросы:

  1. Есть ли хороший тип для представления выходной массив? Сначала я подумал uint1_t было бы идеально, но я слышу это не обязательно представляет один бит в памяти.
  2. Как только я найду шаблон синхронизации в данных, которые я знаю формат следующих битов, как я могу конвертировать кучу 1 и 0 в массив в целые числа, числа с плавающей точкой, двойники, символы и т. д.? Я слышал об использовании союз, но я не думаю, что это будет работать с массив битов.

Ответы [ 4 ]

2 голосов
/ 21 июня 2011

Просто сохраните данные в достаточно большом блоке байтов, а затем переберите биты, используя сдвиг и маскировку для последовательного выделения отдельных битов.

например. чтобы распечатать содержимое буфера в виде отдельных битов:

#include <stdio.h>
#include <stdint.h> // uint8_t et al
#include <limits.h> // CHAR_BIT

uint8_t buffer[256];
int b, bit;

for (b = 0; b < 256; ++b)
{
    for (bit = CHAR_BIT - 1; bit >= 0; --bit)
    {
        uint8_t mask = 1 << bit;
        printf("%2d", (buffer[b] & mask) != 0);
    }
    printf("\n");
}
0 голосов
/ 21 июня 2011

Предполагая большое количество битов на вашем интервале разбора, вы должны собрать бит.Подумайте о круговых буферах, чтобы обеспечить непрерывную работу.Исходная посылка с низкой частотой ошибок по битам и данные с высокой энтропией (т. Е. Байт может принимать все значения, а не только несколько символов), тогда декодирование на основе объединения должно быть лучше.Либо подготовьте биты со сменами перед объединением, либо определите восемь объединений на одну смену и при необходимости вызовите их.

0 голосов
/ 21 июня 2011

Вам придется иметь дело с ними кратными 8 битам и свободно использовать маскировку (& оператор) и сдвиг (>> оператор).Итак, в качестве примера можно привести поток битов MP3 (из http://www.mp3 -tech.org / programmer / frame_header.html ):

AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM

, который может храниться в одном из 32-битная переменная или четыре 8-битные переменные как:

MMLKJJII HGFFEEEE DCCBBAAA AAAAAAAA

Здесь вы должны иметь:

int i = 0;
while (!syncFound)
{
    uint16 sync = data[i] | ((data[i + 1] & 0x07) << 8);
    if (sync == 0x07ff)
    {
        // The first 11 bits represent a sync.
        uint8 version = (data[i + 1] & 0x18) >> 3;
        uint6 layer = (data[i + 1] & 0x60) >> 5);
        // etc...

        syncFound = TRUE;
    } else {
        // current byte is not the start of a frame. check if the next byte is.
        i++;
    }

}

Проверка границ массива может быть утомительной и поэтомутоже может иметь дело с заголовками переменной длины.

0 голосов
/ 21 июня 2011

Храните их в большом буфере Char, и после того, как вы получите свои данные, вы можете конвертировать их в целые числа, плавать с использованием API-интерфейсов преобразования, таких как atoi () atof () и т. Д. Так обычно это делается и в программировании сокетов на языке Си.

...