MATLAB Answers

How to read different bits from a binary file?

3 views (last 30 days)
Eliza
Eliza on 27 Nov 2020
Edited: Eliza on 30 Nov 2020
Hi. I am trying to read a binary file with MATLAB which contains different bits (8-bits and12-bits).
I read stream 1 easily with ('*uint8'). But can you help me to read stream 2 and 3 from the binary file, please?

  0 Comments

Sign in to comment.

Accepted Answer

Sulaymon Eshkabilov
Sulaymon Eshkabilov on 27 Nov 2020
Just employ: 'unit16' instead of 'uint8'.

  0 Comments

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 28 Nov 2020
Edited: Walter Roberson on 28 Nov 2020
I could read stream 1 (8-bits) with a command of "stream1 = fread(fileID, 113:3600112 '*uint8')".
No, do not do that. Instead fseek forward by 112 bytes from the beginning of the file, and fread with size 3600000 with *uint8.
For the second group you do not need to move after the first group. fread 3600000 elements using 'ubit12=>uint16'
For the third group you do not need to move after reading the second group. Do the same fread 3600000 'ubit12=>uint16'
I was concerned because the majority of time that data structures are spoken about as 12 bit, really what is meant is using 16 bits per sample with either the 4 MSB or LSB unused. However the sizes work out perfectly for it to really be 12 bits per sample.

  3 Comments

Walter Roberson
Walter Roberson on 28 Nov 2020
There is a tip for location streams. As I mentioned stream 2 starts at 3600112 and this means that the file is automatically read from the continuation and ends in 3600112 + 3600000 = 72001112. But stream 3 does not start from this point and starts from 9000112!
Stream 2 starts from byte 3600112 . When you read multiple items using ubit12, then MATLAB reads in bytes but breaks them up at the bit level, so when you ask to read 3600000 items, it would read 3600000 * (12/8) = 5400000 bytes. And 3600112 + 540000 = 900112.
filename = tempname();
fid = fopen(filename, 'w');
fwrite(fid, 0:111, 'uint8');
after_header_pos = ftell(fid)
after_header_pos = 112
fwrite(fid, 0:35, 'uint8');
after_stream1_pos = ftell(fid)
after_stream1_pos = 148
stream1_length_bytes = after_stream1_pos - after_header_pos
stream1_length_bytes = 36
fwrite(fid, uint16(256+(0:35)), 'ubit12');
after_stream2_pos = ftell(fid)
after_stream2_pos = 202
stream2_length_bytes = after_stream2_pos - after_stream1_pos
stream2_length_bytes = 54
fwrite(fid, uint16(4095-(0:35)), 'ubit12');
after_stream3_pos = ftell(fid)
after_stream3_pos = 256
stream3_length_bytes = after_stream3_pos - after_stream2_pos
stream3_length_bytes = 54
fclose(fid);
dinfo = dir(filename)
dinfo = struct with fields:
name: 'tpb72ec826_d22b_4f99_a138_245ed8e9d2df' folder: '/tmp' date: '28-Nov-2020 19:57:19' bytes: 256 isdir: 0 datenum: 7.3812e+05
dinfo.bytes
ans = 256
delete(filename)
Observe how I wrote 36 ubit12 items, but that the space used on the disk was 36*(12/8) = 54 bytes.
Walter Roberson
Walter Roberson on 28 Nov 2020
Which sample file are you referring to?
hlen = 112;
s1len = 3600000;
s2len = 3600000;
s3len = 3600000;
headerdata = randi([0 255], 1, hlen);
stream1_data = randi([0 255], 1, s1len);
stream2_data = randi([0 4095], 1, s2len);
stream3_data = randi([0 4095], 1, s3len);
filename = tempname();
%write phase. Get some data into a file with the needed structure
fid = fopen(filename, 'w');
fwrite(fid, headerdata, 'uint8');
after_header_pos = ftell(fid)
after_header_pos = 112
fwrite(fid, stream1_data, 'uint8');
after_stream1_pos = ftell(fid)
after_stream1_pos = 3600112
stream1_length_bytes = after_stream1_pos - after_header_pos
stream1_length_bytes = 3600000
fwrite(fid, stream2_data, 'ubit12');
after_stream2_pos = ftell(fid)
after_stream2_pos = 9000112
stream2_length_bytes = after_stream2_pos - after_stream1_pos
stream2_length_bytes = 5400000
fwrite(fid, stream3_data, 'ubit12');
after_stream3_pos = ftell(fid)
after_stream3_pos = 14400112
stream3_length_bytes = after_stream3_pos - after_stream2_pos
stream3_length_bytes = 5400000
fclose(fid);
dinfo = dir(filename)
dinfo = struct with fields:
name: 'tp0872a127_ae91_4228_8107_b9dab80ae7c0' folder: '/tmp' date: '28-Nov-2020 22:31:21' bytes: 14400112 isdir: 0 datenum: 7.3812e+05
dinfo.bytes
ans = 14400112
%read phase
fid = fopen(filename, 'r');
headerdata_in = fread(fid, [1 hlen], '*uint8');
stream1_data_in = fread(fid, [1 s1len], '*uint8');
stream2_data_in = fread(fid, [1 s2len], 'ubit12=>uint16');
stream3_data_in = fread(fid, [1 s3len], 'ubit12=>uint16');
fclose(fid)
ans = 0
delete(filename)
if isequal(headerdata, headerdata_in)
fprintf('header data all read in okay\n');
else
fprintf('header data mismatch. Wrote\n');
disp(headerdata);
fprintf('received\n');
disp(headerdata_in);
end
header data all read in okay
if isequal(stream1_data, stream1_data_in)
fprintf('stream1 data all read in okay\n');
else
fprintf('stream1 data mismatch. Wrote\n');
disp(stream1_data);
fprintf('received\n');
disp(stream1_data_in);
end
stream1 data all read in okay
if isequal(stream2_data, stream2_data_in)
fprintf('stream2 data all read in okay\n');
else
fprintf('stream2 data mismatch. Wrote\n');
disp(stream2_data);
fprintf('received\n');
disp(stream2_data_in);
end
stream2 data all read in okay
if isequal(stream3_data, stream3_data_in)
fprintf('stream3 data all read in okay\n');
else
fprintf('stream3 data mismatch. Wrote\n');
disp(stream3_data);
fprintf('received\n');
disp(stream3_data_in);
end
stream3 data all read in okay
Eliza
Eliza on 29 Nov 2020
Thanks a lot. Your answer was so helpful.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!