2

Using Matlab R2015a. I'm using fread to read sensor data from a binary file. The data contains multiple precisions. One signal is sampled at 5 times the rate of the other signals. The file is structured as a sequence of batches, where each batch has e.g. 1 sample of signal_A, but 5 samples of signal_B.

I have googled for examples on how to load and format the data fast, but the solutions I have seen only represent cases where there is a single sampling rate, making the solution simpler, as far as I can tell.

What I would like to avoid is the use of for-loops, which is quite slow. See below for an illustration of how the data is arranged in the file, and a simple code example of what I have now.

Any suggestions on how to speed this up?

File structure

clear;
fid = fopen('binaryFile.bin','r');
signal_B = [];

numBatches = Inf; % read all
batchSize = 17; % each batch takes up 17 bytes

% PART 1 (everything that is not signal_B)
batchSerialNumber = fread(fid, numBatches, '*uint32', batchSize-4);
fseek(fid, 4, 'bof'); % rewind
signal_A = fread(fid, numBatches, '*uint16', batchSize-2);
fseek(fid, 6, 'bof'); % rewind
misc_info = fread(fid, numBatches, '*uint8', batchSize-1);

% PART 2 (signal_B)
for i = 1:length(batchSerialNumber)
    fseek(fid, ((i-1)*batchSize) + 7, 'bof'); % set position in file, according to batch number (i)
    signal_B = [signal_B; fread(fid, 5, '*int16')]; % read the 5 samples of signal_B in this batch
end
ctp
  • 163
  • 1
  • 11
  • A small speed-up can be achieved by [not overwriting built-in functions](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab) such as `i`. – Adriaan Oct 02 '15 at 14:17
  • Note taken! Thanks @Adriaan. The speed-up is neglible though... just tested it. – ctp Oct 02 '15 at 14:22
  • Yea, it's a very small speed-up, but it is a bad idea in general to overwrite built-in functions, they're very error prone. – Adriaan Oct 02 '15 at 14:35

1 Answers1

2

More googling and a nice solution eventually appeared... approximately 100 times faster than using for-loop.

clear;
fid = fopen('binaryFile.bin','r');

numBatches = Inf; % read all
batchSize = 17; % each batch takes up 17 bytes

% PART 1 (everything that is not signal_B)
batchSerialNumber = fread(fid, numBatches, '*uint32', batchSize-4);
fseek(fid, 4, 'bof'); % rewind
signal_A = fread(fid, numBatches, '*uint16', batchSize-2);
fseek(fid, 6, 'bof'); % rewind
misc_info = fread(fid, numBatches, '*uint8', batchSize-1);
fseek(fid, 7, 'bof'); % rewind

% PART 2 (signal_B)
signal_B_line_1 = fread(fid, numBatches, '*int16', batchSize-2);
fseek(fid, 9, 'bof');
signal_B_line_2 = fread(fid, numBatches, '*int16', batchSize-2);
fseek(fid, 11, 'bof');
signal_B_line_3 = fread(fid, numBatches, '*int16', batchSize-2);
fseek(fid, 13, 'bof');
signal_B_line_4 = fread(fid, numBatches, '*int16', batchSize-2);
fseek(fid, 15, 'bof');
signal_B_line_5 = fread(fid, numBatches, '*int16', batchSize-2);

signal_B(length(batchSerialNumber)*5,1) = int16(0);

signal_B(1:5:end,1) = signal_B_line_1;
signal_B(2:5:end,1) = signal_B_line_2;
signal_B(3:5:end,1) = signal_B_line_3;
signal_B(4:5:end,1) = signal_B_line_4;
signal_B(5:5:end,1) = signal_B_line_5;
ctp
  • 163
  • 1
  • 11
  • `reshape` can also be used, to accomplish what is done in the last 5 lines of code in the above solution. – ctp Oct 05 '15 at 08:45