function [rec, ref, info] = read2ChInfiniiumBin(fileName)
% READ2CHINFINIIUMBIN reads a raw waveform from an Infiniium binary file

% This function is for use with the binary file format of the Agilent
% Infiniium series of digital real time oscilloscopes. It does not
% implement the full featured file format but assumes that each file only
% contains two waveforms, stored in the raw data format.
% The INFO structure contains header data with information about the
% file size, time and format

% open the file
[fid, message] = fopen(fileName, 'r');
if fid <0
    error('readInfiniiumBin:fileError', message);
end

% check the file header for consistency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cookie = fread(fid, 2, 'uchar=>uchar', 'ieee-le');
info.version = fread(fid, 2, 'uchar=>uchar', 'ieee-le');
if (cookie(1) ~= 'A') || (cookie(2) ~= 'G') || (info.version(1) ~= '1') || (info.version(2) ~= '0')
    error('readInfiniiumBin: wrong file format or version');
end
% size of the file in bytes
info.fileSize = fread(fid, 1,'int32', 'ieee-le');
% I do not make use of this information so far, only reading the first
% waveform in the file
info.numberOfWaveforms = fread(fid, 1, 'int', 'ieee-le');

% check the waveform header, channel 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
waveformHeaderSize = fread(fid, 1, 'int32', 'ieee-le');
waveformType = fread(fid, 1, 'int32', 'ieee-le');
if waveformHeaderSize ~= 140
    error('readInfiniiumBin: wrong waveform header size!');
end
if waveformType ~= 1
    error('readInfiniiumbin: waveform data not in raw format!');
end
% no clue what this field is good for...
waveformBuffer = fread(fid, 1, 'int32', 'ieee-le');
% the number of points recorded in the snapshot
info.points = fread(fid, 1, 'int32', 'ieee-le');
% again, no clue what this field is used for
count = fread(fid, 1, 'int32', 'ieee-le');
% some float gibberish concerning axes scaling - not needed here
xStuff = fread(fid, 1, 'float32', 'ieee-le');
xStuff = fread(fid, 3, 'double', 'ieee-le');
xStuff = fread(fid, 2, 'int32', 'ieee-le');
% date the measurement was made
info.date = fread(fid, 16, 'char=>char', 'ieee-le');
% time the measurement was made
info.time = fread(fid, 16, 'char=>char', 'ieee-le');
% device the measurement was made with
info.device = fread(fid, 24, 'char=>char', 'ieee-le');
% the channel number
info.channel = fread(fid, 16, 'char=>char', 'ieee-le');
% some more stuff i don't know the meaning of
fread(fid, 1, 'double', 'ieee-le');
fread(fid, 1, 'uint32', 'ieee-le');

% check the waveform data header, channel 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if fread(fid, 1, 'int32', 'ieee-le') ~= 12
    error('readInfiniiumBin: wrong data header size!');
end
% check for correct data format
if fread(fid, 1, 'int16', 'ieee-le') ~= 1
    error('readInfiniiumBin: numbers are not stored in floating point format!');
end
% should be 4 for typical float data
info.bytePerPoint = fread(fid, 1, 'int16', 'ieee-le');
% should be bytePerPoint * points
info.bufferSize = fread(fid, 1, 'int32', 'ieee-le');
if info.bufferSize ~= (info.points*info.bytePerPoint)
    error('readInfiniiumBin: data field of unexpected size!');
end

% read date
rec = fread(fid, info.points, 'float32', 'ieee-le');

% check the waveform header, channel 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
waveformHeaderSize = fread(fid, 1, 'int32', 'ieee-le');
waveformType = fread(fid, 1, 'int32', 'ieee-le');
if waveformHeaderSize ~= 140
    error('readInfiniiumBin: wrong waveform header size!');
end
if waveformType ~= 1
    error('readInfiniiumbin: waveform data not in raw format!');
end
% no clue what this field is good for...
waveformBuffer = fread(fid, 1, 'int32', 'ieee-le');
% the number of points recorded in the snapshot
info.points = fread(fid, 1, 'int32', 'ieee-le');
% again, no clue what this field is used for
count = fread(fid, 1, 'int32', 'ieee-le');
% some float gibberish concerning axes scaling - not needed here
xStuff = fread(fid, 1, 'float32', 'ieee-le');
xStuff = fread(fid, 3, 'double', 'ieee-le');
xStuff = fread(fid, 2, 'int32', 'ieee-le');
% date the measurement was made
info.date = fread(fid, 16, 'char=>char', 'ieee-le');
% time the measurement was made
info.time = fread(fid, 16, 'char=>char', 'ieee-le');
% device the measurement was made with
info.device = fread(fid, 24, 'char=>char', 'ieee-le');
% the channel number
info.channel = fread(fid, 16, 'char=>char', 'ieee-le');
% some more stuff i don't know the meaning of
fread(fid, 1, 'double', 'ieee-le');
fread(fid, 1, 'uint32', 'ieee-le');

% check the waveform data header, channel 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if fread(fid, 1, 'int32', 'ieee-le') ~= 12
    error('readInfiniiumBin: wrong data header size!');
end
% check for correct data format
if fread(fid, 1, 'int16', 'ieee-le') ~= 1
    error('readInfiniiumBin: numbers are not stored in floating point format!');
end
% should be 4 for typical float data
info.bytePerPoint = fread(fid, 1, 'int16', 'ieee-le');
% should be bytePerPoint * points
info.bufferSize = fread(fid, 1, 'int32', 'ieee-le');
if info.bufferSize ~= (info.points*info.bytePerPoint)
    error('readInfiniiumBin: data field of unexpected size!');
end

% read date
ref = fread(fid, info.points, 'float32', 'ieee-le');

fclose(fid);
