No BSD License  

Highlights from
Samplify Sampled Data Compression

image thumbnail
from Samplify Sampled Data Compression by Al Wegener
Samplify compresses samples used by A/D and D/A converters

desamplifyFile(infile, outfile)
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);

Contact us at files@mathworks.com