Matlab быстрое преобразование типов данных 4x1 байта в 1x32 байта
Я получаю пакеты двоичных данных, кодирующих аудиосэмплы в виде 24-битных целых чисел без знака. Они должны быть преобразованы в 32-битные целые числа со знаком (дополнение 2) для вывода.
Однако из-за способа разбиения данных на части возможно разделение 24-битного слова через границу пакета. Поэтому я буферизую каждый байт как 8-битное целое число без знака, готовое к преобразованию в группы по 3 (+ 1 байт заполнения нулями), когда все пакеты будут получены.
Я написал следующую функцию для этого, где input
является массивом 1x3 типа uint8
:
% This function takes 3 8-bit decimal values as input and converts them to
% a single, signed, 32 bit decimal number.
% NOTE - little endianness is assumed
function output = convert24bitTo32bit(input)
sign = bitget(input(3), 8); % get sign bit
bytes(3) = bitset(input(3), 8, 0); % zero sign bit
value = typecast([bytes, uint8(0)], 'int32') - logical(sign)*(2^23);
end
Пример можно запустить, используя следующие фрагменты:
% Test 255: 11111111 00000000 00000000
input = uint8([255 0 0]);
output = convert24bitTo32bit(input);
fprintf('\n In: 255 \t Out: %d', output)
% Test -2: 01111111 11111111 11111111
input = uint8([254 255 255]);
output = convert24bitTo32bit(input);
fprintf('\n In: -2 \t Out: %d', output)
Эта функция выполняет свою работу, но на несколько порядков медленнее всего обрабатывает ее.
Есть ли более эффективный способ достижения того же результата? Или встроенную функцию Matlab, которая может обрабатывать более эзотерические преобразования типов данных?
Спасибо
1 ответ
Я бы работал следующим образом:
Заполните ваш
uint8
буферизуйте как можно большим количеством непрерывных 3-байтовых значений:data = uint8([255 0 0 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3]);
Преобразуйте матрицу в матрицу 3xN (обратите внимание, что копирование данных не происходит):
data = reshape(data,3,[]);
Добавьте нулевые байты (вот где происходит копия):
data = [data;zeros(1,size(data,2),'uint8')];
Привести матрицу к
int32
:data = typecast(data(:),'int32');
Вы, кажется, делаете некоторые дополнительные настройки со знаком бит. Я думаю, что вам нужно сделать там пэд не с нулевым байтом, а с байтом 0 или 255, в зависимости от знака третьего байта. Шаг 3 становится:
sign = bitget(data(3:3:end),8);
sign = uint8(sign*255);
data = [data;sign,'uint8')];
[Обратите внимание, что я на самом деле не запускал код выше, пожалуйста, дайте мне знать, если я где-то сделал опечатку!]