How to read different bits from a binary file?
Afficher commentaires plus anciens
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?
Réponse acceptée
Plus de réponses (1)
Walter Roberson
le 28 Nov 2020
Modifié(e) : Walter Roberson
le 28 Nov 2020
1 vote
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 commentaires
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)
fwrite(fid, 0:35, 'uint8');
after_stream1_pos = ftell(fid)
stream1_length_bytes = after_stream1_pos - after_header_pos
fwrite(fid, uint16(256+(0:35)), 'ubit12');
after_stream2_pos = ftell(fid)
stream2_length_bytes = after_stream2_pos - after_stream1_pos
fwrite(fid, uint16(4095-(0:35)), 'ubit12');
after_stream3_pos = ftell(fid)
stream3_length_bytes = after_stream3_pos - after_stream2_pos
fclose(fid);
dinfo = dir(filename)
dinfo.bytes
delete(filename)
Observe how I wrote 36 ubit12 items, but that the space used on the disk was 36*(12/8) = 54 bytes.
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)
fwrite(fid, stream1_data, 'uint8');
after_stream1_pos = ftell(fid)
stream1_length_bytes = after_stream1_pos - after_header_pos
fwrite(fid, stream2_data, 'ubit12');
after_stream2_pos = ftell(fid)
stream2_length_bytes = after_stream2_pos - after_stream1_pos
fwrite(fid, stream3_data, 'ubit12');
after_stream3_pos = ftell(fid)
stream3_length_bytes = after_stream3_pos - after_stream2_pos
fclose(fid);
dinfo = dir(filename)
dinfo.bytes
%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)
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
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
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
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
Eliza
le 29 Nov 2020
Catégories
En savoir plus sur Instrument Connection and Communication dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!