restructure and organize

This commit is contained in:
Silas Oettinghaus
2026-06-22 22:58:35 +02:00
parent 3603fd7853
commit c4f75b7ec4
10 changed files with 108 additions and 116 deletions

View File

@@ -0,0 +1,146 @@
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_cell] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", options.debug_plots);
% Scpe_sig = Scpe_cell{1};
% 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