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

samplifyOptions(varargin)
function options = samplifyOptions(varargin)
%samplifyOptions Create/alter samplify options structure.
%   options = samplifyOptions('param1',value1,'param2',value2,...) creates
%   a Samplify configuration structure options in which the named parameters
%   have the specified values.  Any unspecified parameters are set to [].
%   Case is ignored for parameter names.
%
%   samplifyOptions with no input arguments and no output arguments
%   displays all parameter names and their possible values. Refer to
%   the help for the SAMPLIFY function for more detailed descriptions of
%   what these fields represent. The 'Display' field, which can be either
%   'on' or 'off', controls the verbosity of SAMPLIFY. If this field is set
%   to 'on', SAMPLIFY will the print out the following information to the 
%   screen:
%
%   1) data type (unsigned 16-bit integer, float, etc.)
%   2) compression mode (lossless, fixed-rate, etc.)
%   3) any compression paramters (i.e. 2.0 for 2:1 compression in fixed
%      rate lossy compression)
%
%   options = samplifyOptions (with no input arguments) creates an options
%   structure options where all the fields are set to [].
%
%   Examples
%   --------
%       % Display usage string
%       samplifyOptions
%
%       % Verbose mode, lossless, have Samplify guess input data type
%       opt = samplifyOptions('Display','on','Mode','lossless');

%   Copyright 2005 Samplify Systems LLC
%   Revision: 1.0 (2005/11/23)

persistent operating_modes data_ranges disp_options;
persistent fnames imode icparam idata_type;

fnames = {'Display', 'Mode', 'CompressionParameter', 'InputDataType'};
idisplay = 1; % index into the above
imode = 2; 
icparam = 3;
idata_type = 4;

% if user passes in nothing, display usage
if 0==nargin & 0==nargout
    disp('                Display: [ off | on ]');
    disp('                   Mode: [ lossless | fixedRate | fixedDynRange | NoiseTrak ]');
    disp('   CompressionParameter: [ scalar ]');
    disp('          InputDataType: [ uint8 | int8 | uint16 | int16 | float | double ]');
    return;
end

% create empty samplify options struct
for iField = 1:length(fnames)
   eval(sprintf('options.%s = [];', fnames{iField})); 
end

% very quick sanity check, the # of input args MUST be even
if 0 ~= rem(length(varargin), 2)
    error('Arguments must occur in name-value pairs.');
else
    num_pairs = length(varargin)/2;
end

% March through name-value pairs and fill up structure.
% Try and find Mode specification 1st, because if it has been
% specified we can do some error-checking on CompressionParameter
iModePair = -1;
for iParamName = 1:2:2*num_pairs
    if ~ischar(varargin{iParamName})
       error(sprintf('Expected argument %d to be a string parameter name.', iParamName));
    end
    if strcmpi(varargin{iParamName}, fnames{imode})
        iModePair = iParamName;
        operating_modes = { 'lossless', 'fixedRate', 'fixedDynRange', 'NoiseTrak' };
        options = handle_mode(options, operating_modes, ...
            fnames{imode}, varargin{iParamName+1});
        break;
    end
end

% March through name-value pairs and fill up structure.
% Try and find input data type specification 2nd, because if it has been
% specified we can do even *more* error-checking on CompressionParameter
iDataType = -1;
for iParamName = 1:2:2*num_pairs
    if ~ischar(varargin{iParamName})
       error(sprintf('Expected argument %d to be a string parameter name.', iParamName));
    end
    if strcmpi(varargin{iParamName}, fnames{idata_type})
        iDataType = iParamName;
        data_types = {'uint8', 'int8', 'uint16', 'int16', 'float', 'double'};
        options = handle_data_type(options, data_types, ...
            fnames{idata_type}, varargin{iParamName+1});
        break;
    end
end

% now go through the rest
for iParamName = 1:2:2*num_pairs
    if ~ischar(varargin{iParamName})
       error(sprintf('Expected argument %d to be a string parameter name.', iParamName));
    end    
    if iParamName~=iModePair & iParamName~=iDataType
        if strcmpi(varargin{iParamName}, fnames{icparam})
            options = handle_cparam(options, fnames{icparam}, varargin{iParamName+1});
        elseif strcmpi(varargin{iParamName}, fnames{idisplay})
            disp_options = {'on', 'off'};
            options = handle_display(options, disp_options, ...
                fnames{idisplay}, varargin{iParamName+1});
        end
    end
end

eval(sprintf('error_check_cparam(options.%s,options.%s,options.%s)', ...
        fnames{imode}, fnames{icparam}, fnames{idata_type}));

function options = handle_mode(options, operating_modes, name, value)
%
% HANDLE_MODE
%

if ~ischar(value)
    error('Mode must be a string.');
end

iFound = -1;
for ii=1:length(operating_modes)
   if strcmpi(operating_modes{ii}, value)
       iFound = ii;
       break;
   end
end

if -1 == iFound
    error(['Invalid mode ' value]);
else
    eval(sprintf('options.%s = operating_modes{iFound};', name));
end

function error_check_cparam(mode, cparam, data_type)
%
% ERROR_CHECK_CPARAM
%

if ~isempty(cparam)
    
    if ~isnumeric(cparam) | ~isreal(cparam)
        error('Compression parameter must be a real scalar.');
    end

    if cparam < 0
        error('Compression parameter cannot be negative.');
    end

    if ~isempty(mode)

        % we can check alot more
        if strcmpi(mode, 'fixedRate')
            % this function will do the error checking
            if cparam<1 | cparam>8
                error('Compression ratio must be between 1.0 and 8.0');
            end
        elseif strcmpi(mode, 'fixedDynRange')
            if ~isempty(data_type)
                % 8 bits, no more than 48 dB
                % 16 bits, no more than 96 dB
                if ~isempty(findstr(data_type, '8'))
                   if cparam > 48
                       error('With an 8-bit data type cannot specify more than 48 dB.');
                   end
                elseif ~isempty(findstr(data_type, '16'))
                    if cparam > 96
                        error('With a 16-bit data type cannot specify more than 96 dB.');
                    end
                end
            end
        elseif strcmpi(mode, 'NoiseTrak')
            if cparam<-4 | cparam>4
                error('NoiseTrak margin must be between -4.0 and 4.0 bits.');
            end
        end
    end
end

function options = handle_cparam(options, name, value)

if ~isnumeric(value) | ~isreal(value)
    error('Compression parameter must be a real scalar.');
end

eval(sprintf('options.%s = %d;', name, value));

function options = handle_data_type(options, datatypes, name, value)
%
% HANDLE_DATA_TYPE
%

if ~ischar(value)
    error('Input data type must be a string.');
end

iFound = -1;
for ii=1:length(datatypes)
   if strcmpi(datatypes{ii}, value)
       iFound = ii;
       break;
   end
end

if -1 == iFound
    error(['Invalid range ' value]);
else
    eval(sprintf('options.%s = datatypes{iFound};', name));
end

% lossless mode is NOT supported with floating-point input
bfp = strcmpi('double',options.InputDataType) | strcmpi('float',options.InputDataType);
if bfp & strcmpi('lossless',options.Mode)
    error('Lossless mode not supported with floating-point input.');
end

function options = handle_display(options, disp_options, name, value)
%
% HANDLE_DISPLAY - to do, very similar to above function, should generalize
%                  into a single sub function.
%

if ~ischar(value)
    error('Display must be a string.');
end

iFound = -1;
for ii=1:length(disp_options)
   if strcmpi(disp_options{ii}, value)
       iFound = ii;
       break;
   end
end

if -1 == iFound
    error(['Invalid Display specification ' value]);
else
    eval(sprintf('options.%s = disp_options{iFound};', name));
end

Contact us at files@mathworks.com