146 lines
4.0 KiB
Matlab
146 lines
4.0 KiB
Matlab
function Scpe_sig = preprocessSignal(Scpe_sig, Symbols, fsym, options)
|
|
% PREPROCESSSIGNAL Performs standard preprocessing on a signal
|
|
%
|
|
% Inputs:
|
|
% Scpe_sig - Input signal
|
|
% Symbols - Reference symbols for synchronization
|
|
% fsym - Symbol frequency
|
|
%
|
|
% Outputs:
|
|
% Scpe_sig - Preprocessed signal
|
|
|
|
arguments
|
|
Scpe_sig
|
|
Symbols
|
|
fsym
|
|
options.mode string = "auto"
|
|
options.tx_pulseformer = []
|
|
options.debug_plots (1,1) logical = false
|
|
options.apply_gaussian_filter (1,1) logical = true
|
|
options.gaussian_cutoff_factor (1,1) double = 0.52
|
|
end
|
|
|
|
preprocessMode = resolvePreprocessMode(options.mode, options.tx_pulseformer, Symbols);
|
|
targetFs = 2 * fsym;
|
|
|
|
switch preprocessMode
|
|
case "matched_filter"
|
|
matchedPulseformer = buildMatchedPulseformer(options.tx_pulseformer, Symbols, fsym, targetFs);
|
|
Scpe_sig = matchedPulseformer.process(Scpe_sig);
|
|
case "resample"
|
|
Scpe_sig = Scpe_sig.resample("fs_out", targetFs);
|
|
otherwise
|
|
error('preprocessSignal:InvalidMode', 'Unsupported preprocessing mode "%s".', preprocessMode);
|
|
end
|
|
|
|
[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", options.debug_plots);
|
|
|
|
% Apply Gaussian filter
|
|
if options.apply_gaussian_filter
|
|
Scpe_sig = Filter('filtdegree', 8, "f_cutoff", Symbols.fs.*options.gaussian_cutoff_factor, ...
|
|
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
|
|
"active", true).process(Scpe_sig);
|
|
end
|
|
|
|
%Remove DC offset
|
|
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
|
|
|
end
|
|
|
|
function preprocessMode = resolvePreprocessMode(requestedMode, txPulseformer, Symbols)
|
|
requestedMode = string(requestedMode);
|
|
if requestedMode ~= "auto"
|
|
preprocessMode = requestedMode;
|
|
return
|
|
end
|
|
|
|
pulseformer = txPulseformer;
|
|
if isempty(pulseformer)
|
|
pulseformer = findSignalPulseformer(Symbols);
|
|
end
|
|
|
|
if isRootRaisedCosinePulseformer(pulseformer)
|
|
preprocessMode = "matched_filter";
|
|
else
|
|
preprocessMode = "resample";
|
|
end
|
|
end
|
|
|
|
function tf = isRootRaisedCosinePulseformer(pulseformer)
|
|
tf = false;
|
|
if isempty(pulseformer)
|
|
return
|
|
end
|
|
|
|
pulseValue = readPulseformerField(pulseformer, 'pulse', []);
|
|
if isempty(pulseValue)
|
|
return
|
|
end
|
|
|
|
pulseValue = normalizePulseValue(pulseValue);
|
|
tf = pulseValue == pulseform.rrc;
|
|
end
|
|
|
|
function matchedPulseformer = buildMatchedPulseformer(txPulseformer, Symbols, fsym, targetFs)
|
|
pulseformerMeta = txPulseformer;
|
|
if isempty(pulseformerMeta)
|
|
pulseformerMeta = findSignalPulseformer(Symbols);
|
|
end
|
|
|
|
pulseValue = normalizePulseValue(readPulseformerField(pulseformerMeta, 'pulse', pulseform.rrc));
|
|
alphaValue = readPulseformerField(pulseformerMeta, 'alpha', 0.05);
|
|
pulseLengthValue = readPulseformerField(pulseformerMeta, 'pulselength', 16);
|
|
|
|
if isempty(alphaValue)
|
|
alphaValue = 0.05;
|
|
end
|
|
|
|
matchedPulseformer = Pulseformer( ...
|
|
"fsym", fsym, ...
|
|
"fdac", targetFs, ...
|
|
"pulse", pulseValue, ...
|
|
"pulselength", pulseLengthValue, ...
|
|
"alpha", alphaValue, ...
|
|
"matched", 1);
|
|
end
|
|
|
|
function value = readPulseformerField(pulseformerMeta, fieldName, defaultValue)
|
|
value = defaultValue;
|
|
if isempty(pulseformerMeta)
|
|
return
|
|
end
|
|
|
|
if isstruct(pulseformerMeta) && isfield(pulseformerMeta, fieldName)
|
|
candidate = pulseformerMeta.(fieldName);
|
|
if ~isempty(candidate)
|
|
value = candidate;
|
|
end
|
|
return
|
|
end
|
|
|
|
if isobject(pulseformerMeta) && isprop(pulseformerMeta, fieldName)
|
|
candidate = pulseformerMeta.(fieldName);
|
|
if ~isempty(candidate)
|
|
value = candidate;
|
|
end
|
|
end
|
|
end
|
|
|
|
function pulseValue = normalizePulseValue(rawValue)
|
|
if isa(rawValue, 'pulseform')
|
|
pulseValue = rawValue;
|
|
return
|
|
end
|
|
|
|
if iscell(rawValue)
|
|
rawValue = rawValue{1};
|
|
end
|
|
|
|
if isstring(rawValue) || ischar(rawValue)
|
|
pulseValue = pulseform.(char(string(rawValue)));
|
|
return
|
|
end
|
|
|
|
pulseValue = pulseform(rawValue);
|
|
end
|