function desamplifyFile(infile, outfile)
%desamplifyFile Decompress a signal file using Samplify codec
% desamplifyFile(infile,outfile) decompresses the samplified compressed
% data contained in infile, storing the desamplified data in outfile.
%
% Examples
% --------
% % losslessly compress a binary file with signed 16-bit samples,
% % then decompress this file
% opt = samplifyOptions('Mode','lossless','InputDataType', 'int16');
% infile = 'test_f2_b5_80dB.dat';
% outfile = 'test_f2_b5_80dB.sfy';
% samplifyFile(infile, outfile, opt, 'int16'); % compress
% desamplifyFile(outfile, 'test_f2_b5_80dB.dsy');
%
%
% See also SAMPLIFYOPTIONS, SAMPLIFYFILE
% Copyright 2005 Samplify Systems LLC
% Revision: 1.0 (2005/11/23)
ifid = fopen(infile, 'rb');
if -1 == ifid
error(['Could not open input file ' infile]);
end
tag = fread(ifid, 8, 'uchar'); % string "samplify"
v = fread(ifid, 1, 'uint16'); % version
% verify we understand this version # (check_samplified_file_version will
% throw an error in the event of an invalid version number)
try
bfp = check_samplified_file_version(v); % bfp = boolean floating-point indicator
[format, fmt_16bit, fmt_2scomp, fmt_text, text_facts, ...
num_fmt, delim, sample_count, byte_count ] = parse_header(ifid, bfp);
if bfp
% then right after the old header is a variable length block of
% floating-point normalization factors.
% 1st discern block info based on the length of the uncompressed
% vector
[nwin, nblocks, istart, iend] = block_info(sample_count);
% there are nblocks number of normalization factors
opt.FloatingPointNormalization = fread(ifid, nblocks, 'single');
end
compressed = fread(ifid, inf, 'int16'); % read in the compressed vector
fclose(ifid);
ifid = -1;
% decompress the data
opt.orig_nsamps = sample_count;
opt.InputDataType = get_input_data_type(bfp, fmt_16bit, fmt_2scomp);
uncompressed = desamplify(compressed, opt);
if bfp
if 1==format | 5==format
uncompressed = single(uncompressed);
opt.InputDataType = 'float';
else
uncompressed = double(uncompressed);
opt.InputDataType = 'double';
end
end
% now save desamplified file
if fmt_text
sdelim = samplify_mex(-3, delim);
if ~num_fmt % then decimal
dlmwrite(outfile, uncompressed, sdelim);
else % else hexadecimal
if 1==num_fmt
shex = '0X';
else
shex = '0x';
end
write_hex_file(outfile, uncompressed, opt.InputDataType, shex, sdelim);
end
else
ofid = fopen(outfile, 'wb+');
if -1 == ofid
error(['Could not open input file ' outfile]);
end
fwrite(ofid, uncompressed, opt.InputDataType);
fclose(ofid);
end
catch
if -1 ~= ifid
fclose(ifid);
end
error(lasterr);
end
function bfp = check_samplified_file_version(v)
VERSION = samplify_mex(0); % [major minor]
% check: does this .sfy file correspond to a floating-point samplified
% file?
VERSION_FP = floating_point_samplify_version(VERSION);
% now we need to verify that we understand this file format
vfile_major = bitand(v,255);
vfile_minor = bitshift(v,-8);
if prod( single(VERSION_FP == [vfile_major vfile_minor]) )
bfp = 1;
return;
elseif vfile_minor<=VERSION(2) & vfile_major<=VERSION(1)
bfp = 0;
return;
else
error(sprintf('Samplified file version # %d.%d is incompatible with this version of Samplify.', ...
vfile_major, vfile_minor));
end
function [format, fmt_16bit, fmt_2scomp, fmt_text, text_facts, ...
num_fmt, delim, sample_count, byte_count ] = parse_header(fid, bfp)
%
% PARSE_HEADER
%
format = fread(fid, 1, 'uint16'); % original file's numerical format
fmt_16bit = bitshift(bitand(format,2),-1);
fmt_2scomp = bitand(format, 1);
fmt_text = 0;
text_facts = 0;
if format >= 4
fmt_text = bitand(format, 2);
end
text_facts = fread(fid, 1, 'uint8');
num_fmt = bitand(text_facts,15);
delim = bitshift(text_facts,-4);
sample_count = fread(fid, 1, 'uint32');
byte_count = fread(fid, 1, 'uint32');
if bfp
if format>4
fmt_text = 1;
else
fmt_text = 0;
end
end
function stype = get_input_data_type(bfp, fmt_16bit, fmt_2scomp)
%
% GET_INPUT_DATA_TYPE
%
if bfp
stype = 'int16';
else
if fmt_16bit
bits = 16;
else
bits = 8;
end
if fmt_2scomp
stype = sprintf('int%d', bits);
else
stype = sprintf('uint%d', bits);
end
end
function write_hex_file(outfile, uncompressed, dt, shex, sdelim)
%
% WRITE_HEX_FILE
%
fid = fopen(outfile, 'wt+');
if -1 == fid
error(['Could not open input file ' outfile]);
end
try
if 'i'==dt(1)
% two-complement signed
nibbles = str2num(dt(4:end))/4;
[cutoff, minval] = twoscomp(dt);
inegative = find(uncompressed<0);
uncompressed = double(uncompressed);
uncompressed(inegative) = -minval + uncompressed(inegative);
else % unsigned
nibbles = str2num(dt(5:end))/4;
end
if '\n' == sdelim
for ii=1:length(uncompressed)
sample = uncompressed(ii);
fprintf(fid, '%s%s\n', shex, dec2hex(sample,nibbles));
end
else
for ii=1:length(uncompressed)
sample = uncompressed(ii);
fprintf(fid, '%s%s%c', shex, dec2hex(sample,nibbles), sdelim);
end
end
catch
fclose(fid);
error(lasterr);
end
fclose(fid);