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